ARQ × A-MPDU measured: contract holds, CCX telemetry and goodput do not - #373
Conversation
Bench (arq_e2e_delivery.sh, 8812CU drone -> 8812EU DUT, MCS3/512B unicast, retry 8, batch-8 feed): - Delivery contract: acked_undelivered=0 in every BA arm — admission-gated ACK semantics survive AGG_EN unchanged. - CCX telemetry structurally degrades under aggregation: ~60% of requested SPE_RPT reports never emitted (per-aggregate suppression pattern), every report says retries=0 (BlockAck retransmit cycles invisible), no frame ever carries multiple reports. Tag-gap accounting is un-aggregated-only; receipts are the delivery truth under A-MPDU. - Goodput at 4k fps saturation demand: BA delivered -8% vs the identical un-aggregated feed (208,792 vs 226,691) — the +30% figure is high-MCS broadcast; at low-MCS ARQ shapes the BA machinery costs more than the preamble amortization saves. Both numbers now paired in the docs. Analyzer: per-tag frame reconciliation (last-state-wins, max-retries) so a multi-report BA future stays measurable; reduces to the old identity at one report per frame (parity-verified on recorded runs). Harness: DRONE_AMPDU / DRONE_BATCH knobs. Closes #364 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PR Summary by QodoARQ × A‑MPDU bench results: update docs plus ARQ E2E harness/analyzer
AI Description
Diagram
High-Level Assessment
Files changed (4)
|
Code Review by Qodo
1. Env quotes break knobs
|
… loud AMPDU parse failure - arqe2e.verdict: "ok" split into "ok_reports" (raw report events) + "ok_frames" (per-tag reconciled, what the identity uses) + explicit "multi_report_frames" — equal today, divergent once BA multi-reports exist, and no consumer has to guess which unit it is reading. - docs/aggregation.md: the ARQ-shape bullet now carries the contract numbers beside the goodput ones — au=0 under BA, the control's +97 (0.04%) ACK-loss duplicates, and why the BA arm's 1.1% shortfall cannot be decomposed (CCX degradation, next bullet). - env_config: DEVOURER_TX_AMPDU_MODE parse failure now warns instead of silently leaving A-MPDU off (a silent no-op invalidates a bench run); same contract as the RETRY_FALLBACK warn below it. Verified on-adapter. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Executes the #364 measurement plan end-to-end on the bench rig (8812CU drone → 8812EU DUT duplex, 8814AU witness; MCS3/512 B unicast, hardware ACK, retry 8, batch-8 feed via
send_packets).Findings
1. The delivery contract survives aggregation.
acked_undelivered = 0in every BA arm (A-MPDU0/31) exactly as in every per-frame-ACK arm — the ACK-horizon law is unchanged: admission-gated, declines under congestion, no phantom ACKs introduced by the BA session.2. Per-frame CCX accounting does NOT survive AGG_EN (the new negative result, now in
docs/aggregation.md):Reports are suppressed in whole-aggregate bunches, retransmission cycles are invisible (BA retries happen below CCX), and the multi-report-per-MPDU model never materializes. The SW_DEFINE tag-gap drop signal is therefore accounting-grade only for un-aggregated frames; under A-MPDU the windowed RX receipts (#363) are the only delivery truth.
3. No goodput win at the ARQ shape — a measured loss. At 4 k fps saturation demand, BA delivered −8% vs the identical un-aggregated feed (208,792 vs 226,691 frames). The docs' +30% is a high-MCS broadcast near-PHY-ceiling number; at MCS3 the preamble amortization is small and the BA machinery costs more than it saves. Both numbers now sit side by side in
docs/aggregation.md+ theCLAUDE.mdpointer.Recommendation shipped in docs: do not enable A-MPDU on the ARQ/FPV link as measured; if revisited (high-MCS, receipts-only accounting), the analyzer is ready — see below.
Code
tests/arq_e2e_analyze.py: per-tag frame reconciliation (last-state-wins, max-retries, multi-report counter) so a multi-report BA future stays measurable; reduces to the previous identity at one report per frame — parity-verified byte-identical on recorded per-frame-ACK runs (clean baseline delta-0/au=0 and spsc au=5739 both reproduce).tests/arq_e2e_delivery.sh:DRONE_AMPDU/DRONE_BATCHknobs (aggregation only forms with a back-to-back queue feed).docs/aggregation.md,CLAUDE.md: the two adversarial pairings above.Closes #364
🤖 Generated with Claude Code