Reduce firmware USB transfer size from 16KB to 8KB #1203
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR reduces the size of firmware-side USB transfers from 16KB to 8KB: a quarter of the available buffer, rather than half.
This provides greatly improved throughput in practice:
With 16KB transfers, Windows and macOS would both typically fail to maintain sufficient USB throughput above 16-17Msps sample rates, with only Linux sustaining 20Msps. With 8KB transfers, all three operating systems now sustain 20Msps.
With 16KB transfers, Linux would sustain 20Msps TX but with occasional brief underruns. With 8KB transfers, there are none. Buffer stats printed from
hackrf_transfer -B
clearly show a higher and more consistent level of data in the buffer.The smaller transfer size helps because it reduces sensitivity to latency. Previously, the device had to NAK the IN/OUT tokens from the host until there was a full 16KB of data or buffer space ready. Using the largest possible chunks is efficient, but means the device can miss chances to send some data when it could. If the host then polls late, it may be hard to recover.
It seems like the 16KB size interacted poorly with Windows and macOS, which would both give up polling just before the next chunk became ready, and then retry too late to recover before a shortfall occured. Linux probably performed better due to polling more aggressively.
8KB has been chosen as a sweet spot: going further down to 4KB transfers has been tested but collapses the RX performance.