https://gitlab.synchro.net/main/sbbs/-/commit/85956c15d7e9a6d5a389f859
Modified Files:
docs/zmodem_comparison.md src/sbbs3/zmodem.c
Log Message:
docs/zmodem: the "115.8 MB/s buffered floor" was a one-second sleep
The comparison doc's headline mystery was that every sender built on
zmodem.c stalled at 115.8 MB/s on a 256 MiB localhost send while lrzsz
reached 203.9, on less CPU per byte and only 30% utilization. Successive revisions called it an engine CPU limit, then an unexplained I/O stall in
the measuring tool. It was the 1-second receive-buffer purge on the normal
send path: 1.32 s of work plus 1.00 s of sleep is 2.32 s, and 256 MiB over
2.32 s is 115.8 MB/s. Every buffered sender reported the same number
because each was paying the same fixed second.
Re-measured with that fixed and with the ZFILE retransmit behind it: sexyz 203.9 MB/s, ztx_buf 203.9, lsz 203.8, all in 1.32 s. The engine now ties lrzsz's own inlined loop, which retires the "what could a non-blocking
sender reach" question this doc kept open.
Record why the benchmark could not see it, since the blind spot outlived several rounds of analysis: the harness sends one file per run, so a
per-file cost lands once in a goodput figure built to divide fixed costs
away; the rate-capped rows refunded it from banked tokens and read as link-bound; and the CPU/context-switch diagnostics cannot see a sleeping
poll() by construction. Section 2 now says to time a batch of small files
for anything suspected of costing per file.
Bump zmodem_ver() to 2.5 for the two protocol fixes.
Found and reported by Uwe Ohse, maintainer of lrzsz, who measured sexyz at
5.9 KB/s against lrzsz's 10.2 KB/s sending five small files over a
simulated 115200 bps line, and supplied the protocol dump and strace.
Co-Authored-By: Claude Opus 5 (1M context) <
noreply@anthropic.com>
---
þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net