Zero to Photon:
USB sends 0s faster than
it sends 1s
2024 . 4 . 17
While developing Photon's USB 2.0 stack, at one point I attempted to benchmark its optimal USB throughput by configuring its STM32 to transmit an endless stream of 0x00 bytes, which resulted in a throughput of ~42 MB/sec. To test something unrelated, I changed the implementation to send 0xFF bytes instead, and noticed that the throughput dropped to ~38 MB/sec.

Surely I must've messed something up in my benchmarking. Changing the dummy values back to 0x00 though, the throughput reverted back to ~42 MB/sec. Wat.


Wat

Perplexing at first, it turns out this is the expected behavior of USB and is an artifact of its electrical protocol. There are two facts important to understanding why:
  1. USB doesn't have an explicit clock signal; instead, the transitions of the data line itself are used to synchronize the independent clocks of the host and the peripheral.
  2. USB transmits a binary 0 by toggling its data line voltage, and transmits a binary 1 by keeping its data line voltage constant relative to the previous bit.

This scheme (called NRZS) presents a problem when there's a long stream of binary 1s: without additional machinery, there would be no transitions on the data line to synchronize the clock of the host and peripheral.


Bit Stuffing

To ensure that sufficient data-line transitions occur to permit clock synchronization, USB performs bit-stuffing, which is where the data line is forced to toggle if six binary 1 values are transmitted in a row. This contrived transition is ignored by the receiver and therefore doesn't result in a 0 in the data stream.

The cost of this contrived transition is that USB transfer times have a data-dependency: as I accidentally stumbled on, a stream of binary 1 values maximizes bit-stuffing and results in a markedly lower throughput.

This doesn't affect real-world data much, since most real data doesn't contain long streams of 1s, but nonetheless I was surprised to learn that USB's throughput depends on the data being transmitted.