ISSUE-041: retry_timeout 偏紧致 spurious Go-Back-N — sim_time 虚高 11×
发现日期:2026-06-07
修复日期:2026-06-07
状态:已修复
类型:建模参数 bug — lossless 网络下 retry_timeout (10μs) 小于最坏 ACK RTT (~50-70μs),误触发 Go-Back-N spurious 重传,抬高 sim_time
关联 issue:ISSUE-040 (同在 RC Link 重传路径;ISSUE-040 修对了"重传时 credit 记账",本 issue 修"重传本不该发生")
结论速览
根因:G5 是 lossless 网络 (CBFC credit 流控保证无丢包),但 driver.rs 把 retry_timeout_ns 硬编码成 10000 (10μs)。在 256KB×32chip alltoall 高拥塞下,ACK 往返延迟 (过 clos 多跳 + RX ACK MERGE 排队,实测最坏 ~50-70μs) 远超 10μs。retry timer 误判"ACK 没来 = 丢包",触发 Go-Back-N 重传整批 WaitAck slot。
由于网络 lossless,这些重传全部是 spurious (虚假重传):RX 早已收到原始包,重传到达后被 PSN duplicate detection 丢弃 + 返还 credit。但重传占用链路与仿真时间,滚雪球把 sim_time 抬高 11.1× (clos-32-256kb: 7,393,476 ns vs 真实 664,447 ns)。
关键判据:全程 incomplete_txns = 0 / cbfc_residue = 0 / psn_gaps = 0 — 数据完整无真丢包,证明每一次重传都是多余的。
问题现象
ISSUE-040 (方案 C) 修复后 16-cell golden 全过,但 4 个 256KB×32chip cell 的 sim_time 异常大。固定 clos-32-ecmp-256kb,扫 retry_timeout (仅改此参数,其余不变):
| retry_timeout (ns) | sim_time (ns) | incomplete | nak (retry 触发) | retx (重传 packet) | maxhit |
|---|---|---|---|---|---|
| 10000 (旧值) | 7,393,476 | 0 | 67364 | 7,725,698 | 17836 |
| 20000 | 4,357,815 | 0 | 31492 | 4,239,152 | 5688 |
| 30000 | 3,241,465 | 0 | 18420 | 2,957,840 | 1784 |
| 50000 | 1,945,836 | 0 | 6868 | 1,470,744 | 0 |
| 70000 | 664,447 | 0 | 0 | 0 | 0 |
| 100000 / 1ms / 100ms | 664,447 | 0 | 0 | 0 | 0 |
sim_time 随 retry_timeout 单调下降,在 70μs 处 nak 归 0、收敛到真实值 664,447 ns。最坏 ACK RTT ∈ (50μs, 70μs]。
调查过程
Phase 0 预期行为
- 原始硬件 spec (RCLINK_AFH_SPEC §10.3 + §5.10):
RETRY_TIMER_CFG(0x0040 bit[16:13]) 是重传次数阈值 (= max_retry), spec 未硬性规定 retry timer 的时长,是可配置硬件寄存器。故 G5 的10000ns是建模选值,非 spec 强制。 - slot 状态机 (spec P37): "slot 报文被仲裁发出时由 WAIT_GRANT 变 WAIT_ACK;有重传请求时由 WAIT_ACK 变 WAIT_GRANT" — 重传机制存在,但触发时长由实现定。
Phase 1 反馈环 + 量化
写临时插桩 (d_retry_nak / d_retry_retx / d_retry_maxhit 旁路 stats) + 扫 retry_timeout,得上表。决定性实验:retry_timeout 从 10μs 调到 ≥70μs, incomplete 始终 0 而 retx 从 772 万降到 0, sim_time 降 11× — 证明这些重传对数据完整性毫无贡献,纯属 spurious。
业界对标 (见下节)
RDMA / TCP / 仿真器三方一致:lossless 网络的 retransmit timer 应是"固定大值兜底",不该被正常 ACK RTT 触发。
根因分析
| 错误模式 | 实例 | 后果 |
|---|---|---|
| lossless 网络的 retry timer 设得小于最坏 ACK RTT | driver.rs retry_timeout_ns=10000 vs 实测最坏 ACK RTT ~50-70μs | 正常 ACK 未到即误判丢包 → spurious Go-Back-N → sim_time 虚高 11× |
为什么 256KB×32chip 是触发配置
- 256KB / pair, frame ≤ MPS(16KB) → 每 pair ~16 frame; 32chip alltoall 单 chip 对 31 个对端 → 高 in-flight。
- clos 多跳 (chip→tor→spine→tor→chip) + RX ACK MERGE 排队,ACK 往返被拉到 ~50-70μs。
- 小 cell (8/16 chip, 64KB) ACK RTT 远小于 10μs,不触发,故 ISSUE-040 修复后它们的 baseline 数值正确。
业界对比
| 来源 | retransmit timeout 设计 | 对本 issue 的启示 |
|---|---|---|
| ns3-rdma / HPCC (最可比:lossless RoCEv2 + Go-Back-N + PFC) | 固定 500μs (m_waitAckTimer); PFC lossless 下几乎不触发,纯兜底链路错误 | lossless 仿真用固定大值,不自适应 |
| IBTA local ACK timeout (§12.7.34) | 固定 4.096μs × 2^field, field 0-31;实践 field=14 ≈ 67ms 兜底,非自适应,无指数退避 | 设成远超 RTT 的兜底 |
| TCP RTO (RFC 6298) | 自适应 SRTT + 4×RTTVAR,初始 1s,指数退避 | WAN RTT 跨度大才需自适应;数据中心 lossless 不需要 |
| BookSim2 / gem5 Garnet | 不建模 retransmit (credit 流控保证 buffer 不溢出 = 无丢包) | lossless 下 retry 本可省略 |
综合:lossless 仿真主流是"固定大值兜底"或"不建模"。G5 选固定大值 (保留 retry 路径作真异常兜底),取值 = 最坏 RTT × 10-20。
解决方案
采用:driver.rs retry_timeout_ns 10000 → 1_000_000 (1ms)。
取值依据:
- 最坏 ACK RTT (clos-32-256kb, golden 最重 cell) 实测 ~50-70μs; ×14 安全系数 ≈ 1ms。
- 1ms >
rc_link_livenessdeadlock 阈值 (500μs):让 deadlock 探测器做真异常兜底,retry timer 在 lossless 下退化为"几乎不触发"。 - 与 ns3-rdma (500μs) 同量级,思路与 IBTA 实践 (67ms 兜底) 一致。
涉及文件:
perfmodel/evaluation/g5/src/driver.rs— retry_timeout_ns 改值 + 依据注释perfmodel/evaluation/g5/tests/golden/baseline.json— 重新生成 (4 个 256KB×32chip cell sim_time 从虚高 11× 修正到真实值)
不改 rc_link_credit.rs 默认值 (已是 500_000,合理);仅修 driver 的 override。
验证
- retry_timeout 扫描: nak 在 ≥70μs 归 0, sim_time 收敛 664,447 ns (见现象表)。
- golden 重新生成:16/16 PASS, 4 个重 cell sim_time 修正 (clos-32-256kb 7.39M → 664K)。
- 回归
cargo test --release:全量 0 failed (golden_compare 用新 baseline 比对通过)。 - 守恒不变:全 16 cell incomplete/unsent/residue/psn_gaps/event_balance 仍全 0。
Lessons Learned
- lossless 网络的 retry timer 不该被正常 ACK RTT 触发:G5 用 credit 流控保证 lossless,重传永不真正需要。retry_timeout 必须远超最坏 ACK RTT,否则高拥塞下 ACK 排队延迟就足以误触发 spurious 重传。
- spurious 重传是"功能正确但结果错误"的隐蔽 bug:数据完整 (incomplete=0) + 守恒通过 (residue=0),所有正确性断言全绿,但 sim_time 错 11×。守恒/活性断言抓不到它——需要 Golden 回归 (数值锁定) 或蜕变 MR (标度关系) 才能暴露。这印证了 Phase 2C 四层防线里 Golden 层的必要性。
- 建模参数要有实测依据,不拍脑袋:旧
10000ns无量化来源。新值经 retry_timeout 扫描 + ACK RTT 实测 + 业界三方对标确定 (类 ISSUE-039 死锁阈值 max×10 的定值方法)。 - Golden baseline 可能锁死 buggy 行为:ISSUE-040 修复后生成的 baseline 把虚高 11× 的 sim_time 冻结了。提醒:baseline 生成前,数值的物理合理性需独立 sanity check (本 issue 即由"sim_time 异常大"触发)。
遗留问题
- 更大配置 (64/128 chip, 1MB) 的最坏 ACK RTT 未实测:1ms 对 golden 范围 (≤32chip×256KB) 有 14× 余量;若未来扩到极大规模且 ACK RTT 逼近 500μs, deadlock 阈值 (500μs) 会先于 retry 误触发 (那是 ISSUE-039 阈值体系的独立问题,需同步上调)。
- retry 在 lossless G5 中是否应彻底移除:当前保留作真异常兜底,但 deadlock 探测器已覆盖真死锁。是否删 retry 路径简化状态机,是独立设计决策,不在本 issue 范围。