https://gitlab.synchro.net/main/sbbs/-/commit/9627d6504cecd3c53ff66c47
Modified Files:
docs/zmodem_comparison.md src/bench/zmodem/README.md
Log Message:
docs/zmodem, bench: re-measure after Deuce's send-path work; root-cause sexyz
Every throughput figure is re-measured in one interleaved batch (256 MB,
three passes, spread under 2%) so the tables are internally consistent
instead of splicing runs from different days: lrzsz 203.9, zmodem.c
rev 2.3 buffered floor 115.8, sexyz receiving 113.3, Forsberg 96.9,
zmodem.c rev 2.2 buffered floor 91.9, sexyz sending 11.5 MB/s.
Deuce's 2026-07-24 work on the shared send path (class-table byte
classifier, slicing-by-4 CRC-32, hoisted escape mask with noinline cold
paths, buffered fcrc32) moved the buffered floor 91.9 -> 115.8, +26%,
which SyncTERM inherits. The doc's old "second, shared lever, pending"
framing is replaced with what actually shipped.
Root-cause the sexyz sender properly rather than asserting it.
send_byte() takes the ring mutex twice per byte while output_thread
hot-loops on the same mutex: 44 CPU-seconds per 256 MB against lsz's
0.95, 1,464,130 voluntary context switches against 1,402, one futex per
17 bytes with 37% contended, and ~94-byte socket writes. A full sweep
of OutbufSize, OutbufHighwaterMark and OutbufDrainTimeout is flat inside
noise, so this is not a tuning problem and should not be chased as one.
Record the prototype ladder and what each one proved. Buffering the
producer removes the entire sexyz-specific penalty -- 115.8 MB/s at 1.0 CPU-second, exactly the engine ceiling -- but six variants now fail the
3x error-injection gate that the shipped per-byte sender passes. Two
results are worth keeping: rate-capping the batched sender to the
shipped sender's own 11 MB/s still fails while the shipped sender passes
3/3, so it is not an artifact of the higher data rate; and going single-threaded with a buffered send_byte holds full speed, drops
context switches to lsz's level, and reaches 2/3, leaving blocking
sendbuf() as the one missing piece. The recommendation is now what lrz actually is: single-threaded, buffered, non-blocking output with select
on both directions.
Also note the failure modes that cost time to rediscover (a void flush
callback swallowing a failed write, a sticky error latch spinning on zmodem_send_raw ERROR, position accounting desync) and that a
single-stream localhost benchmark cannot see per-byte CPU wins above
~100 MB/s -- two of Deuce's optimizations measure zero here because his
six interleaved 1 GiB transfers are CPU-saturated and this is not.
No code changes: all prototypes were measured out-of-tree and discarded.
Refs #1195, #1196.
Co-Authored-By: Claude Opus 4.8 (1M context) <
noreply@anthropic.com>
--- SBBSecho 3.37-Linux
* Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)