-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Switch to faster serial #25
Switch to faster serial #25
Conversation
Should be backwards compatible, except that commands ending in just newline (\n) are accepted in addition to commands ending in carriage return + newline (\r\n).
Thanks @carterturn , I'm keen to dig into this once it's ready. The speed improvements shown in the other repo certainly seem to make this worthwhile! I'd like to merge this after #26, so keep that in mind (it'll be a squash merge though so there is no point rebasing yet). If you had time to review that PR too, I would appreciate it. It should mean you wont need to include the uf2 files explicitly (they'll get built by GitHub actions and uploaded as an artefact for testing, and then built for a release after merging and tagging) |
Should be much faster.
Well, I see what the problem was when I tried this. I included Also, I think it is really interesting that the binary blobs are less than half their size when using this serial comms mode. That's kind-of wild. |
Binary mode is now implemented, and I have tested programming for a single-clock-pulse sequence. Waiting to merge for #26 sounds good. I am a bit pleased to have fewer binary blobs in git repositories. Curiously, I ran into compilation issues when not using the "extern C" directive, but I suspect there are some cmake options that could fix that. I suppose this serial code does not have many features that the pico SDK version does have, though that is indeed a surprising difference in executable size. |
@carterturn I've had a go at doing some performance tests and I'm not getting as impressive of results as for the prawn_do. Basically, there is a floor on the binary write of ~200 ms regardless of the number of instructions and it appears to be the same floor as doing individual serial writes. I don't see increases in timing until at least 150 instructions are sent for the block binary (obviously the individual writes are much slower). Test script with instr = 250
dummy_data = np.tile([[100, 4],
[1000000, 1]],
(instr, 1))
# individual serial writes
for i in range(dummy_data.shape[0]):
prawn.write(f'set 0 {i:d} {dummy_data[i,0]:d} {dummy_data[i,1]:d}\r\n'.encode())
_ = prawn.readline().decode()
# block binary of same data
prawn.write(f'setb 0 0 {dummy_data.shape[0]:d}\r\n'.encode())
serial_buffer = b''
for i, (dur, reps) in enumerate(dummy_data):
serial_buffer += struct.pack('<I', dur)
serial_buffer += struct.pack('<I', reps)
prawn.write(serial_buffer)
resp = prawn.readline().decode() Timing summary using
It would appear there is something in the firmware that is really bogging us down. Nothing obvious is jumping out at me. Only real differences I see are that we recalculate the |
I am an idiot. The jupyter cells I was running those timing snippets in have a
Edit: stupidity continues. My dummy data is alternating two instructions. So the total number of instructions written is actually |
As another optimization that may be worth implementing, the for-loop building of the serial buffer string doesn't scale especially well to these very high values. If the data we want to write is in a well-ordered numpy array, we could use the instr = 4000
seq = np.array([[100, 4], [1000000, 1]], dtype='<u4')
dummy_data = np.tile(seq, (instr//2, 1))
# for loop
serial_buffer = b''
for i in range(dummy_data.shape[0]):
serial_buffer += struct.pack('<I', dummy_data[i,0])
serial_buffer += struct.pack('<I', dummy_data[i,1])
# numpy
serial_buffer2 = dummy_data.tobytes()
serial_buffer == serial_buffer2 ## returns True Timing using python 3.8 and %%timit magic
May be worth implementing that in the labscript device. |
Thank you for the updated test, that would have been a confusing bug to try to replicate. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is all good to go, but am just now realizing the README hasn't been updated with the new setb
command. Probably should do that before merging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything looks good to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While checking write speeds, I accidentally broke the binary writes in a way that should be preventable. We should probably address that before merging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Going to go ahead and merge this. Suspect the program command has the same issue as the digital output board, but I say we fix it later.
This pull request replaces the Pi Pico SDK serial over USB CDC with a custom implementation in TinyUSB that is typically faster.
It aims to be backwards compatible, though it may also allow commands terminated in only newline (\n) to be accepted in addition to the carriage return + newline termination (\r\n).
Not ready to merge yet, as a binary mode should still be added for even faster programming.