feat(core): scale the receive path to the new multi-Gbps ceiling

- REPLAY_WINDOW 32768 -> 131072: the anti-replay bitmap covered the
  120 ms loss window only to ~2 Gbps; the client now delivers ~4.8 Gbps
  wire, where a late-but-valid Wi-Fi-retried datagram would have been
  dropped as 'older than the window' — false loss. 16 KiB/session
  covers ~12 Gbps.
- RECV_BATCH 32 -> 128: syscall rate stays ~3.4k/s at 430k pkt/s and
  each pump iteration drains the kernel buffer deeper (ring 64->256 KB,
  client sessions only). flush_backlog's iteration cap rescaled to keep
  its ~190 MB guard equivalent.
- PUNKTFUNK_GSO gate is now value-aware: '=0' used to ENABLE GSO on
  Linux (presence check) while disabling Windows USO. GSO stays OPT-IN,
  deliberately: A/B'd twice today — it cuts send-thread CPU ~30% but
  its 16-packet line-rate trains cost delivered throughput on a
  constrained fabric (2.5GbE-hop pair: peak 2453 -> 1908 Mbps and 0.4%
  loss at a rate sendmmsg carries clean). Flipping the default belongs
  with pace-aware chunk spacing (plan Phase 1.2/1.3). docs-site row
  corrected to match.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 19:22:40 +02:00
parent 160914c48b
commit 1a559e8d5e
4 changed files with 28 additions and 16 deletions
+11 -4
View File
@@ -1,7 +1,7 @@
//! Real UDP datagram transport — native sockets, no async runtime.
//!
//! Send is batched via `sendmmsg` ([`Transport::send_batch`], ≤64/syscall) and recv via `recvmmsg`
//! ([`Transport::recv_batch`], ≤32/syscall into a reused ring) on Linux AND Android (which is
//! ([`Transport::recv_batch`], ≤128/syscall into a reused ring) on Linux AND Android (which is
//! `target_os = "android"`, not `"linux"` — it needs its own bionic binding, see [`android_mmsg`])
//! — the 1 Gbps+ syscall lever (~125k → a few-k syscalls/sec at line rate). The host additionally
//! paces each frame's send across the frame interval (see `punktfunk1.rs::paced_submit`) so a real
@@ -111,8 +111,14 @@ fn mmsghdrs(iovs: &mut [libc::iovec]) -> Vec<mmsghdr> {
.collect()
}
/// UDP GSO enable state (process-wide). Opt-in via `PUNKTFUNK_GSO` — it's new unsafe hot-path code,
/// and the auto-fallback (latch off on any GSO syscall error) covers kernels/paths without support.
/// 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).
#[cfg(target_os = "linux")]
mod gso {
use std::sync::atomic::{AtomicU8, Ordering};
@@ -123,7 +129,8 @@ mod gso {
1 => true,
2 => false,
_ => {
let on = std::env::var_os("PUNKTFUNK_GSO").is_some();
// Opt-in: on only when PUNKTFUNK_GSO is set to something other than "0".
let on = std::env::var("PUNKTFUNK_GSO").is_ok_and(|v| v != "0");
STATE.store(if on { 1 } else { 2 }, Ordering::Relaxed);
on
}