feat(host): pace-aware send chunking — high-rate frames pace honestly instead of blasting
ci / docs-site (push) Successful in 50s
ci / web (push) Successful in 52s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 10s
decky / build-publish (push) Successful in 23s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 10s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 12s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 10s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 10s
ci / bench (push) Successful in 6m0s
flatpak / build-publish (push) Failing after 8m9s
docker / deploy-docs (push) Successful in 25s
deb / build-publish (push) Successful in 12m48s
android / android (push) Successful in 13m11s
arch / build-publish (push) Successful in 15m13s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 13m32s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 16m29s
ci / rust (push) Successful in 23m9s
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 4m48s
windows-msix / package (x64, C:\Users\Public\ffmpeg, , x86_64-pc-windows-msvc, C:\t) (push) Successful in 4m1s
windows / build (aarch64-pc-windows-msvc) (push) Successful in 5m29s
windows / build (x86_64-pc-windows-msvc) (push) Successful in 6m35s
windows-host / package (push) Successful in 14m25s
apple / swift (push) Successful in 5m13s
release / apple (push) Successful in 26m56s
apple / screenshots (push) Successful in 20m2s

Phase 1.2: the native plane's pace chunks are rate-adaptive — 16 packets at
today's rates, coarsening until the per-chunk interval clears the 500 µs sleep
floor, capped at 64 (the GSO segment limit). Decouples the syscall batch from
the pace step, so a ≥1 Gbps frame's overflow keeps real sleeps between chunks
(and costs 4× fewer syscalls) instead of collapsing into an unpaced blast.

Phase 1.3: the auto microburst cap scales with the frame — max(128 KB, the
AU's wire bytes / 4) — so high-rate frames burst a bounded quarter and pace
the rest; PUNKTFUNK_PACE_BURST_KB now pins an absolute override.

GameStream plane untouched (its schedule stays pinned by the deterministic
tests, now also asserting budget-independence). Linux GSO latch-off warns
once (was silent; USO already warned).

Linux GSO default stays OPT-IN: the post-1.2/1.3 A/B on the 2.5GbE-hop pair
(.21 → M3 Ultra) reproduced the regression bit-for-bit — 2452 Mbps sendmmsg
vs 1909 GSO peak, 0.4% loss at 1500 where sendmmsg is clean. The super-buffer
trains lose on the constrained hop in the transport path itself (per-AU
probe sends, no video pacer involved), so the block is fabric evidence, not
pacing readiness. Control sweep on this build matched the sendmmsg baseline
exactly (2452); loss-harness recovery curve identical; workspace clippy +
tests green on .21.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 21:38:06 +02:00
parent a2433d77cf
commit 5a384fe788
3 changed files with 156 additions and 43 deletions
+14 -8
View File
@@ -112,13 +112,16 @@ fn mmsghdrs(iovs: &mut [libc::iovec]) -> Vec<mmsghdr> {
}
/// UDP GSO enable state (process-wide). **Opt-in** (`PUNKTFUNK_GSO=1`) — and deliberately so,
/// measured twice on 2026-07-14: GSO cuts send-thread CPU ~30% at 1250 Mbps, but its 16-packet
/// line-rate trains cost real delivered throughput on a constrained fabric (the 2.5GbE-hop pair:
/// peak 2453 → 1908 Mbps, and 0.4% loss appeared at a rate the sendmmsg path carries clean).
/// Flipping the default belongs together with pace-aware chunk scaling (plan Phase 1.2/1.3 in
/// `design/throughput-beyond-1gbps.md`), which spaces the super-buffers instead of skipping
/// sub-floor sleeps. NOTE the gate is value-aware: `PUNKTFUNK_GSO=0` explicitly disables (it
/// used to key on env *presence*, so `=0` ENABLED it here while disabling Windows USO).
/// measured three times on 2026-07-14: GSO cuts send-thread CPU ~30% at 1250 Mbps, but its
/// line-rate super-buffer trains cost real delivered throughput on a constrained fabric (the
/// 2.5GbE-hop pair: peak 2452 → 1909 Mbps, and 0.4% loss at a rate sendmmsg carries clean).
/// The third A/B ran WITH pace-aware chunk scaling landed (plan Phase 1.2/1.3 in
/// `design/throughput-beyond-1gbps.md`) and reproduced the regression bit-for-bit — the trains
/// lose on the hop's queue in the transport path itself (per-AU super-buffers, no video pacer
/// involved), so the default stays opt-in on fabric evidence, not on pacing readiness. Revisit
/// with a bare-metal Linux host on a clean 10G path. NOTE the gate is value-aware:
/// `PUNKTFUNK_GSO=0` explicitly disables (it used to key on env *presence*, so `=0` ENABLED
/// it here while disabling Windows USO).
#[cfg(target_os = "linux")]
mod gso {
use std::sync::atomic::{AtomicU8, Ordering};
@@ -137,8 +140,11 @@ mod gso {
}
}
/// Latch GSO off for the process after a GSO syscall error (unsupported kernel/path).
/// Warns once — a mid-session downshift to sendmmsg should be visible, not silent.
pub fn disable() {
STATE.store(2, Ordering::Relaxed);
if STATE.swap(2, Ordering::Relaxed) != 2 {
tracing::warn!("Linux UDP GSO unsupported on this path — falling back to sendmmsg");
}
}
}