跳到主要内容

ISSUE-030:族无关路由调查 — FlowMeta 硬编码修复 + packet_spray / flowlet_ar 在 SG2262 RCLINK + alltoallv 下物理不适用

发现日期:2026-06-01 状态:已修复(代码 bug)+ 已剔除(packet_spray / flowlet_ar 从研究) 类型:实现 bug + 建模决策(三层级联调查) 影响范围:G5 仿真 PacketSprayPolicy / PerFlowletAdaptivePolicy。不影响 family-aware 算法(ECMP / dmodk / DOR / UGAL / shortest_path)——这些算法 packet_id / sim_time_ns 是否准确都不影响其行为。


问题现象

调查跨越三个阶段,根因逐层揭示:

阶段 1:packet_spray 数值与 shortest_path 精确相等(bug 假象)

--profile l1-grid --ns 32 后,fat-tree 三个 variant 上 packet_spray 与 shortest_path latency 精确相等

(N=32, S1@1.6, EP=32, compact, tok=192)shortest_pathpacket_spray差异
fat-tree-k8(default cpb=8)55.70 μs55.70 μs0
fat-tree-k8-pure(cpb=1)54.25 μs54.25 μs0
fat-tree-k435.50 μs35.50 μs0

其他拓扑(torus / dragonfly / hypercube / hyperx)上 packet_spray ≠ SP。只在 fat-tree 上精确相等,排除偶然。

阶段 2:修复 packet_id 后 packet_spray 雪崩(协议层问题暴露)

定位 + 修复 c2c_network.rs:312 硬编码 packet_id: 0 后,packet_spray latency 从 33.98μs 雪崩到 8084.65μs(240× 比 SP 慢)。同时 PerFlowletAdaptive 的 sim_time_ns 也硬编码 0,顺手修了。

阶段 3:flowlet_ar 重跑后 17/25 cell 大幅恶化(workload 层问题暴露)

删 28 行 flowlet_ar 旧数据(bug 状态产出),重跑 l1-grid + validate 对比:

模式cell 数新 latency旧 latency变化
A. 雪崩 ~8000μs78018-8050 μs28-41 μs+20000-28000%
B. 中爆 ~500μs10514-533 μs21-34 μs+1400-2280%
C. 不变722-33 μs22-33 μs0.0%

模式 A/B 都是 NAK storm,模式 C 是 flowlet 切换后路径"碰巧"等价。


调查过程

Phase 0:预期行为(spec 依据)

项目 Spec(docs/specs/路由模块设计.md):

  • @tbl-spec-route-19 (line 563):flow.packet_id: 报文标识,per-packet 算法的决策维度
  • @tbl-spec-route-20 (line 580):PacketSprayPolicy:按 packet_id 决策

算法 Spec(LetFlow,Vanini et al., NSDI 2017):

Flowlets are bursts of packets within a flow, separated by idle periods larger than the maximum network delay difference between paths.

Phase 1:症状定位

grep "packet_id" perfmodel/evaluation/g5/src/:

// c2c_network.rs:312
let flow = FlowMeta {
flow_id,
packet_id: 0, // ← 硬编码 bug
sim_time_ns: 0.0, // ← 同一构造点同样硬编码
};

调用方 7 处都不传 packet_id / sim_time_ns,所以 PacketSpray (0 % paths.len()) == 0 永远选 path[0](≡ shortest_path);PerFlowletAdaptive now - last_ts == 0 永远不大于 gap → 永不切换 flowlet(≡ first-hop ECMP)。

Phase 2:假设排序与排除

#假设验证结果
1c2c_network.rs:312 packet_id=0 硬编码是唯一根因✓ 确认
2flowlet_ar 同样受影响(last_packet_id 比对永不切换)✓ 确认
3Layer 1 PacketSprayStrategy 在 fat-tree 上返回单路径✗ 排除(find_equal_cost_paths c0→c30 返回 4 条路径)
4G5 Policy descriptor 派遣错策略✗ 排除(sim_engine.py:96-100 按 decision_frequency 正确派 PacketSprayPolicy)

Phase 3:修复 + 集成测试

c2c_network.next_hoppacket_id: u64 + sim_time_ns: f64 参数,7 个调用点构造:

调用点packet_id 来源sim_time_ns 来源
paxi.rs (frame_done)(txn_id << 16) | frame_seqnow
paxi.rs (pack_done)(txn_id << 16) | psnnow
paxi.rs (CreditReturn)0(控制平面,静态路由)t
shared.rs (reverse ACK)0(ACK 静态路由)t
switch.rs (3 处)(txn_id << 16) | psnnow / fwd.finish_ns

新增集成测试:

  • packet_id_threaded_to_packet_spray_policy(4-path 网络 × 16 packet_id,断言至少命中 2 path)
  • sim_time_ns_triggers_flowlet_switch(50 flow × 4 path × gap=100ns × sim_time=500ns,断言至少 5 flow 切换 path)

cargo test --release 356/356 pass,ECMP/SP/DOR/dmodk/UGAL total_time 浮点完全相等(surgical 验证)。

Phase 4:packet_spray 雪崩根因(协议层)

RCLINK Spec(C:\Users\DELL\Documents\项目\PAXI\最新\RCLINK_AFH_SPEC_v2.4.md):

  • P7L9:TYPE1 支持端到端保护,支持 Go-Back-N 端到端重传
  • P7L11:TYPE2 不支持端到端保护
  • P36L11 + P37L15:TYPE1 队列严格 in-order 仲裁

PAXI UG(UV_ORI_001_PAXI_SUE2.0_UserGuide_V2R0P5_20260130_release.md P19L11-12):

PAXI does not guarantee ordering for data across different virtual channels. The upper layer must maintain the order or support out-of-order operations.

含义

顺序保证
PAXI 跨 VC不保证(上层负责)
RCLINK TYPE1 单 VC 内强保证(Go-Back-N)
RCLINK TYPE2不保证(但非可靠传输)

Go-Back-N:PSN gap 触发 sender 重传 N, N+1, ... 全部后续包。packet_spray 散布到多 path → 路径延迟差异 → 必然乱序到达 → NAK storm。8084μs 是物理正确的 Go-Back-N 雪崩代价。

Phase 5:flowlet_ar 重跑根因(workload 层)

[假设] Agent 修复 sim_time_ns 后报告 "validate 9 cell 全不变,flowlet_ar 与 ECMP 同值"——推断 alltoallv burst 模式下 flowlet 不触发。

[实验] 系统重跑 24 个 flowlet_ar cell 对比旧值:17/25 cell 大幅恶化(模式 A/B),agent 推断错。

[查代码] per_flowlet_adaptive.rs:92-118 切换条件:now - last_pkt_ts > flowlet_gap_ns。当前 flowlet_gap_ns = 5000ns

[实验] alltoallv 实际时序:

  • N=32 chips × 31 dst 并发 flow → 单 flow 相邻包间隔被 round-robin 拉长到 几μs
  • 这个间隔正好跨越 5μs 阈值 → 频繁触发"假 idle"flowlet 切换
  • 但旧路径包仍在传播(~3-5μs 链路延迟)→ 切换 = 同 (src, qp) PSN 乱序 → Go-Back-N NAK storm

[查 spec] LetFlow 论文核心假设:flowlets 之间是 app 层自然 idle——前一段包真的已经在网络里排空了。

[假设] alltoallv 不满足 LetFlow 假设 — 确认

特征LetFlow 假设alltoallv 实际
单 flow 内 idle 间隙有(app think time)几乎没有(后台批量持续 push)
典型 inter-packet 间隔app 决定,可以 50μs+sender round-robin,几μs
适用 workloadweb search / RPC / storage❌ alltoallv / allreduce 后台批量

[实验] 调参实验(理论分析):

flowlet_gap_ns物理结果信息价值
小(< 网络 RTT ~5μs)频繁触发,乱序到达 → NAK storm 雪崩数据无效
大(> 任何真实间隔,如 50μs+)永不触发 flowlet → 退化为 first-hop ECMP数据 ≡ ECMP,无信息量

alltoallv 上不存在"甜点 gap"——同一参数既要 > 网络传播时间(避免乱序)又要 < workload 真实 idle 间隔(才能触发),而 alltoallv 没有真实 idle。


根因分析(三层级联)

  1. 实现 bug(已修):c2c_network.next_hop 隐式构造 FlowMeta 时硬编码 packet_id: 0 + sim_time_ns: 0.0,违反 spec @tbl-spec-route-19 / 20。这层是直接的代码错误。

  2. 协议层不兼容(剔除 packet_spray):SG2262 RCLINK TYPE1 用 Go-Back-N 强 in-order,与 packet_spray 必然乱序的特性冲突。这是硬件协议层级的硬约束,修代码改变不了

  3. Workload 层不兼容(剔除 flowlet_ar):LetFlow 假设 app 有 idle 间隙,alltoallv 没有,所以 flowlet_gap_ns 调小则乱序(同 Go-Back-N 问题)、调大则永不触发。alltoallv workload 范式与 LetFlow 不匹配


解决方案

实施清单

操作文件状态
修代码:加 packet_id: u64 + sim_time_ns: f64 参数 + 7 调用点构造 + 2 集成测试c2c_network.rs + event_handlers/paxi.rs / shared.rs / switch.rs
G5 顺手优化:trace 守卫 + chip_name 反向表 + Cargo LTO(单 cell 9.56s → 6.99s)multi_chip.rs / c2c_network.rs / Cargo.toml
剔除 packet_spray:_cell_descriptors_for_n 移除 packet_spray 行 + MAIN3 用 dmodk 替代 + DB 清 90 行run_alltoallv.py + DB
剔除 flowlet_ar:_mp() 返回 [] + validate 用 shortest_path 替代 + DB 清 24 行run_alltoallv.py + DB
文档说明:design.md §路由表删族无关列 + 合并剔除论证小节 + 计数 41/46 → 35/39 → 25/28(回到 原始 routing 集)design.md
保留 Policy 实现:packet_spray.rs / per_flowlet_adaptive.rs不删✓(未来硬件 / workload 变化可重新启用)

业界对照(支持剔除决定)

协议 / 算法与 SG2262 alltoallv 的兼容性
packet_spray on IB RC❌(IB 严格 PSN,同 RCLINK)
packet_spray on UEC 1.0✓(UEC spec 强制 OOO RX 配套)
packet_spray on Spectrum-X / EFA✓(应用层 / 交换机处理 reorder)
flowlet_ar on web/storage workload✓(LetFlow 论文场景)
flowlet_ar on alltoallv workload❌(无 idle 间隙)

业界共识:packet_spray 需要 OOO RX 配套;flowlet_ar 需要 workload 有自然 idle。两者在 SG2262 RCLINK + alltoallv 组合下都不满足前提条件。


验证

修复正确性

检验项结果
cargo test --release --lib356/356 pass(含新增 packet_id / sim_time_ns 集成测试)
ECMP / SP / DOR / dmodk / UGAL 修复前后 total_time浮点完全相等(surgical 验证)
validate 9 cell全 pass
smoke 1 cell4s pass

剔除完成

# DB 已清
python -c "import sqlite3; con=sqlite3.connect('data/llm_evaluations.db'); \
print(con.execute(\"SELECT COUNT(*) FROM comm_eval_results WHERE experiment_id=36 \
AND json_extract(config_snapshot,'\$.routing') IN ('packet_spray','flowlet_ar')\").fetchone()[0])"
# 预期 0

# DB 现状: 234 rows / 5 routings (ECMP 115 / DOR 76 / SP 30 / dmodk 10 / UGAL 3)

Lessons Learned / Prevention

测试层缺口(导致 bug 长期未被发现)

测试层级覆盖是否覆盖根因
Unit (PacketSprayPolicy)给策略喂不同 packet_id 会散布✗ 测试自造 FlowMeta,不验证生产路径
Unit (c2c_network)next_hop 内部构造 FlowMeta 填什么 packet_id✗ 缺
Integration (G5 全仿真)跑完一次 alltoallv 后 packet 真的散布到多 path 吗✗ 缺

经验:每个 ForwardingPolicy 都需要"跑完整 sim 后断言行为符合 spec"的集成测试,单元测试给策略喂数据不算数。本次新增的两个集成测试已 lock 这个边界。

流程层缺口 — 路由算法引入双重检查清单

ISSUE-030 的三层级联根因暴露:

当前流程缺的环节
加 routing algorithm检查算法对 RX/transport 的协议层依赖 → 缺
检查 G5 sim 支持检查算法的 workload 范式假设 → 缺
检查目标硬件是否原生支持 → 缺

建议docs/specs/路由模块设计.md 加 "Strategy 引入检查清单":

  1. 网络层:需要哪种 path enumeration(single / multi / distribution)?
  2. 协议层:对 RX/transport 有什么 in-order / OOO / SACK 要求?
  3. Workload 范式:假设 sender 行为如何(burst / idle / steady)?
  4. 目标硬件实测:查硬件 spec 验证协议兼容性
  5. 目标 workload 实测:跑一个代表 cell 验证 workload 假设成立

如果 v1.2.0 引入 packet_spray / v1.3.2 引入 flowlet_ar 时走过这个清单,会立刻发现冲突——不会有今天这次 "Implementation → Bug fix → Discover incompatibility" 的弯路

研究价值

两个剔除都不是"做减法",而是"做了 spec-grounded 的负面结论"

  • packet_spray 业界推广(UEC 2025 / NVIDIA Spectrum-X)默认硬件已升级到 OOO-capable;SG2262 用户不能套用业界"应该用 packet_spray"的结论
  • flowlet_ar 业界推广(NVIDIA / Cisco)默认 workload 有 idle gap;MoE alltoallv 用户不能套用业界"flowlet 比 ECMP 好"的结论
  • 输出"在 SG2262 RCLINK + alltoallv 组合下,只有 ECMP / dmodk / DOR / UGAL / SP 是真正可用的路由"= 有决策价值的负面结论

遗留问题

  • ACK 反向路径 packet_id 语义未在 spec 明确:本次修复用 0(静态路由),建议项目 spec v1.4 补充
  • PerHopAdaptivePolicy 的 packet_id 用法:未深查,decision_frequency=per_hop 可能有类似问题,需单独验证
  • 未来硬件升级路径:若 SG2262 后续版本支持 OOO RX(UEC 兼容),可重新评估 packet_spray
  • 不同 workload 评估:若评估 LLM serving 等有 think time 的 workload,flowlet_ar 可能恢复价值
  • flowlet_gap_ns 的 tuning guideline:本研究论证它在 alltoallv 上没有甜点,但通用 workload 的 tuning(应 > max 路径间延迟差)值得写进 spec