fix(core/speed-test): packet-level throughput + paced burst (kill the 0/100% cliff)
The punktfunk/1 speed test was unusable across every client/host: at the start of a burst a little data got through, then everything read as dropped (~10 MB total). Two compounding bugs: 1. Receive side measured throughput from fully-reassembled FLAG_PROBE *access units* only. The instant loss crossed the 20% FEC budget no AU completed, so the figure cliffed to 0 / 100% loss even though most bytes still arrived — a binary cliff, not a graded measurement. 2. Send side blasted each filler AU (up to 256 KB ≈ 200 packets) into the socket buffer in one unpaced batch, unlike the real video path which paces. On a small buffer (e.g. the Steam Deck's 416 KB) a single AU overflowed it, so the test measured self-inflicted buffer overflow instead of the link. Fixes: - Host `run_probe_burst` keeps each AU a small (~16 KB) burst and paces by the byte budget, mirroring `paced_submit`; reports the WIRE packets the kernel accepted and the ones the send buffer dropped (stat deltas), separating host-side drops from link loss. - `ProbeResult` gains `wire_packets_sent` + `send_dropped` (back-compat decode: a 21-byte pre-wire-stats result still decodes, new fields 0). - Clients (probe + connector) count delivered traffic at the packet level via `session.stats()` deltas over the burst window, so throughput/loss degrade gracefully. Connector freezes the delivered figure when the host report lands so resumed video can't inflate it. New `ProbeOutcome`/`PunktfunkProbeResult` fields: `host_drop_pct`, `wire_packets_sent`, `send_dropped`. Validated on loopback (graded 142→1391 Mbps, host_drop/link_loss split correctly, no cliff) and live against the Deck: clean to ~200 Mbps goodput / 273 Mbps wire at 0% link loss, host send buffer the wall above that (the lever-#1 target). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -468,22 +468,29 @@ typedef struct {
|
||||
|
||||
// A speed-test measurement, filled by [`punktfunk_connection_probe_result`]. `done` is 0 until
|
||||
// the host's end-of-burst report lands, then 1 (the numbers are final). `throughput_kbps` is the
|
||||
// measured goodput to drive a bitrate choice from; `loss_pct` is the delivery loss at that rate.
|
||||
// delivered wire throughput to drive a bitrate choice from; `loss_pct` is the link loss and
|
||||
// `host_drop_pct` the host-side send-buffer drop (raise `net.core.wmem_max`) — they're measured
|
||||
// separately so a host that can't keep up reads differently from a lossy link.
|
||||
typedef struct {
|
||||
// 1 once the host's end-of-burst report arrived (measurement final); else 0 (partial).
|
||||
uint8_t done;
|
||||
// Probe payload bytes / packets the client received.
|
||||
// Delivered wire bytes (header + shard) / packets the client received during the burst.
|
||||
uint64_t recv_bytes;
|
||||
uint32_t recv_packets;
|
||||
// Probe payload bytes / packets the host reported sending.
|
||||
// Application goodput bytes / access units the host offered.
|
||||
uint64_t host_bytes;
|
||||
uint32_t host_packets;
|
||||
// Client-measured receive window (first→last probe AU), milliseconds.
|
||||
// The host's measured burst duration, milliseconds (the throughput denominator).
|
||||
uint32_t elapsed_ms;
|
||||
// Measured goodput = `recv_bytes * 8 / elapsed_ms` (kilobits/second).
|
||||
// Delivered wire throughput = `recv_bytes * 8 / elapsed_ms` (kilobits/second).
|
||||
uint32_t throughput_kbps;
|
||||
// Delivery loss `(host_bytes - recv_bytes) / host_bytes` as a percentage (0 if unknown).
|
||||
// Link loss `(wire_packets_sent − recv_packets) / wire_packets_sent` as a percentage.
|
||||
float loss_pct;
|
||||
// Host-side send-buffer drop `send_dropped / (wire_packets_sent + send_dropped)`, percent.
|
||||
float host_drop_pct;
|
||||
// Wire packets the host put on the link, and the ones its send buffer dropped (raw counts).
|
||||
uint32_t wire_packets_sent;
|
||||
uint32_t send_dropped;
|
||||
} PunktfunkProbeResult;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
Reference in New Issue
Block a user