跳到主要内容

ISSUE-018-multi-unit-alpha-oscillation

ISSUE-018: PAXI LG 调度周期共振导致通信延迟随消息大小非单调

发现日期:2026-05-12 修复日期:2026-05-13 状态已修复 类型调度策略 bug 根因:chip-level round-robin counter 在 frames/unit % num_link_groups == 0 时与 CDMA 注入门控阶梯 earliest_ready 发生 phase lock 修复:PAXI LG 分配改用 hash-based ITLV(对齐硬件 spec SG2262 C2C方案.docx §"ITLV (Hash)"),spec 同步升级 G5-RC-Link v1.4.0 影响范围:所有通过 PAXI 的通信场景,N=2 单步 Ring 通信最显著(M=512/576/1024 等 case 出现反物理 M 增大延迟减小)

诊断历史:本 issue 经过 5 轮诊断。前 4 轮对根因的解读(ACK MERGE drain / housekeeping 污染 / CHS Transfer last_done_ns 太早 / multi-LG 仿真器内部同步爆发)均不完整或不准确。第 5 轮通过 RcFrameDone / SUBMIT / AckArrived debug trace 定位到 PAXI lg_rr_counterframes/unit 的整除共振。前 4 轮诊断保留作推理过程记录。


问题现象

固定 N=2 Ring AllGather,扫描 M ∈ [32KB, 4MB],提取等效 α(= G5 总延迟 - β·wire),观察到 α 在 0.27~0.73 μs 之间非单调震荡:

M (KB)β·wire (μs)G5 total (μs)α_eff (μs)
320.0460.4130.367
640.0910.4560.365
1280.1820.5860.404
2560.3640.8720.508
5120.7281.4570.729 ← 局部峰
7681.0921.5360.444
8961.2741.5990.325
9601.3651.6590.294 ← 局部谷
10001.4222.0570.635 ← 跳起 0.34
10241.4562.1210.665 ← 局部峰
11001.5641.8730.309
11521.6381.9430.305
11801.6781.9550.277
15002.1332.7210.588 ← 又跳起
20482.9133.4490.536
40965.8256.1050.280

α_eff 极差 0.46 μs,远超合理误差范围(spec v1.1.2 α_start = 0.30 μs,理论上应该是常量)。

物理上 α 与消息大小无关(startup latency 不应随 M 变化),所以这种震荡是建模产生的人工现象,不是真实硬件行为。

实际影响:TPS186 baseline doc 中 MLA AG(M=1.125 MB → α_eff=0.305)和 MLA RS(M=1.0 MB → α_eff=0.665)恰好踩到曲线相邻的"谷"和"峰",造成 G5/Math 比值看起来差异巨大(0.83x vs 1.15x),实际是 M 选择的偶然,与 AG/RS 本身建模无关。


调查过程

  • [实验] scripts/debug_g5_rs_vs_ag.py:对同一 M 分别跑 AG 和 RS,G5 输出完全一致(total_sim_time 字节对齐)。→ 排除"RS 特有的 reduce-after-receive 路径"假设。AG 和 RS 在 G5 expand 路径完全等价,都调用 helpers::expand_ring_steps

  • [查代码] perfmodel/evaluation/g5/src/collective/allgather.rs:12-17reducescatter.rs:11-16 都调用同一个 helper,CDMACommand 生成结构相同。

  • [查代码] perfmodel/evaluation/g5/src/collective/expand.rs:104-109 multi-channel 分包逻辑:

    let c = total_cdma_units.max(1);
    if c > 1 {
    op.data_bytes = (op.data_bytes as f64 / c as f64).ceil() as u64;
    }

    total_cdma_units = dies_per_chip × cdmas_per_die = 2 × 4 = 8configs/chips/SG2262.yaml:61,79),所以 SG2262 默认每条 CommOp 平分到 8 个 Unit 并发。

  • [假设 1] 震荡来自 PAXI rsp 通道的 ack tail。 → 排除。trace 验证:tail 区间事件 = link_busy/idle on link_cX_cY_rsp,长度 ~500ns,但在所有 M 下都存在,不能解释震荡的高低差异。

  • [假设 2] 震荡来自 RS 特有的 reduce 计算延迟。 → 排除。同 M 下 AG=RS 完全相等。

  • [假设 3] 震荡来自 multi-CDMA Unit 分包与 PAXI 包边界的耦合。 → 确认根因scripts/debug_g5_units_isolation.py 测试:强制 cdmas_per_die=1, dies_per_chip=1(total_cdma_units=1)后,α_eff 在所有 M 下稳定在 0.35~0.37 μs,没有震荡。仅当 total_cdma_units=8(默认)时出现震荡。

    M (KB)α @ 1 unitα @ 8 units
    2560.3640.508
    5120.3640.729
    9600.3640.294
    10240.3640.665
    11800.3550.277
    15000.3540.588

根因分析

multi-Unit 并发场景下,每个 CDMA Unit 拿到 data_bytes / 8 字节,独立按 PAXI max_payload = 1344 B 分包:

configs/chips/SG2262.yaml:99: max_payload: 1344(每 RC Link 包最大数据字节)

每 Unit 包数 = ceil(unit_bytes / 1344),最后一包字节数 = unit_bytes - (N_pkt - 1) × 1344

8 个 Unit 同时发送时,critical path 由"最慢完成的 Unit"决定。当不同 Unit 的"最后小包"在时间上错落分布到 link 上时,会产生追加占用尾巴——尾巴长度与最后小包大小、相邻 Unit 完成时刻的相对位置有关,呈非单调变化。

具体表现为 α_eff 在 M 跨过某些"分包边界 + Unit 同步边界"组合时跳跃。简单的 M / 8 / 1344 余数分析不足以完全预测峰谷位置——还涉及 PAXI line_rate(tx.line_rate_per_lg_bytes_per_ns: 50)、credit_size、datapath_bytes、Unit 启动错位等多个因素的耦合。


Spec / 文档依据

项目 Specdocs/specs/互联通信延迟数学建模.md v1.1.2):

§3.3 α_start = ddr_r + ddr_w + 2·(noc + stack) = 0.30 μs,与消息大小 M 无关。

互联通信文档docs/interconnect/04-集合通信/07-all-gather.md line 100):

$T_{\text{Ring-AG}} = (N-1)\alpha + \frac{(N-1)M}{N\beta}$

理论模型中 α 是 per-step 常量,不应随 M 震荡。G5 的 α_eff 震荡是仿真器多通道分包行为产生的,模型层无对应建模

推断

  • multi-Unit 分包是 SG2262 实际硬件行为(8 个 CDMA Unit 物理独立),所以"Unit 分包导致 packet 不对齐"在硬件上也确实存在
  • 但硬件上 PAXI line_rate / credit pool / scheduler 可能比 G5 当前建模更平滑(如硬件 datapath 流水线掩盖小包尾巴),G5 当前的离散事件建模可能放大了这种边界效应

未解决

  • 真实 SG2262 硬件实测在 M=512KB / 1024KB 是否也出现类似的 α 跳变?需要硬件测量数据对照
  • 哪个具体边界(分包余数、credit 同步、Unit dep chain)权重最大?需要进一步 trace 拆解

业界对比(暂缺)

NCCL 不暴露 per-CDMA-Unit 延迟分布,业界对 multi-engine 分包是否产生 α-jitter 没有公开实测数据。后续若获得 SG2262 实测,再补对照。


解决方案

备选方案

方案描述优点缺点
A维持现状,doc 注明震荡现象,建议工程用多个 M 平均或 M > 2MB(α 占比小)做对比不改代码,工作量最小doc 表读起来 G5/Math 比值仍然有锯齿
Bexpand.rs 改 multi-Unit 分包逻辑:用 round-robin packet 级分配代替"先切大块再各自分包"平滑 α需要重写 multi-channel 逻辑,可能影响其他场景(hierarchical / AllToAll)
C修 PAXI 模型让最后一包不产生 tail(如包大小 padding 到 max_payload 整数倍)物理上更接近硬件 datapath 流水线行为改 PAXI 层,影响所有原语;padding 也会改变 wire bytes 统计
D给 baseline 测试加 multi-Unit 调度的"平均化"层(同 M 跑多次,固定 jitter 平均),仅用于 baseline 报告不动 G5 核心需要新模块,且不解决问题本质

采用方案

采用 A(先记录,不修代码)

理由:

  1. 震荡只发生在 N=2 单步通信场景,N≥4 多步 pipeline 会摊薄
  2. SG2262 实际硬件是否有同样的边界效应未知,盲改 G5 可能脱离真实硬件
  3. doc 表只是 baseline 对比,加一段说明即可

后续触发条件升级到 B/C

  • 拿到 SG2262 实测发现硬件没有这种震荡 → 走 C(修 PAXI 模型让仿真匹配实测)
  • 拿到 SG2262 实测发现硬件有但幅度不同 → 走 B(调整分包策略)
  • 业务需要 N=2 单步通信的 G5 稳定结果 → 走 B 或 D

涉及文件(A 方案)

文件改动说明
docs/validation/通信原语评估-TPS186/comm-primitive.md§差异分析 增加一段,说明 N=2 单步通信下 G5 α_eff 随 M 震荡是 multi-Unit 分包效应,不是 RS/AG 建模差异

验证

复现命令:

# 完整 M 扫描(确认震荡)
python scripts/debug_g5_m_sweep.py

# 1 unit vs 8 unit 对比(确认 multi-Unit 是根因)
python scripts/debug_g5_units_isolation.py

# AG vs RS 在同 M 下完全等价(确认不是 RS 特有建模问题)
python scripts/debug_g5_rs_vs_ag.py

预期:

  • M 扫描:α_eff 在 0.27~0.73 μs 之间锯齿震荡
  • 1 unit:α_eff 在所有 M 下稳定 ~0.36 μs(无震荡)
  • AG vs RS:同 M 下 total_sim_time 完全相等

遗留问题

  1. 拿到 SG2262 真实硬件实测后,对比 α_eff 是否同样震荡。决定是否升级到方案 B/C
  2. 进一步用 trace 拆解到具体 PAXI 事件级别,找哪个边界(分包余数 / credit / scheduler)权重最大
  3. 评估对 N≥4 多步通信的影响(推测被 pipeline 摊薄到不可见,但需要扫一次验证)

后续诊断(2026-05-12)

为决定是否走 frame-level 重构(方案 C),跑了一组参数扫描诊断scripts/debug_jitter_root_cause.py),对照 4 个变体在 M ∈ {512KB, 960KB, 1024KB, 1180KB} 下的 α_eff:

变体α 范围 (μs)α 极差解读
baseline (8 LG, poll=4ns)0.28 ~ 0.730.45已知 jitter
variant_A (1 LG)4.93 ~ 10.95.98单 LG 整体拖 8×,无法横向对比
variant_B (poll=0.001ns 准 per-packet ACK)0.27 ~ 0.730.45与 baseline 完全相同
variant_C (poll=1000ns 大窗口 ACK 聚合)0.63 ~ 1.671.04比 baseline 还大 2.3×

@tbl-issue-018-diag jitter 根因参数扫描对照

关键结论

  1. ACK MERGE 聚合粒度不是 jitter 来源 —— variant_B (poll=0.001ns,准 per-packet ACK) 与 baseline (poll=4ns) 极差完全相同。这证伪了 "frame-level ACK 聚合可消除 jitter" 的假设
  2. variant_C 反向:ACK 窗口越大反而恶化 jitter,说明现 baseline 的 poll=4ns 已经接近最优 ACK 聚合度
  3. multi-LG 路径影响无法独立验证:单 LG 整体拖慢 8×,无法分离"调度散布"与"带宽损失"的贡献

真因剩余假设

  • 推测:multi-LG 间 packet 到达时刻随 M 跳跃,max(LG_completion) 在某些 M 处触发"最后一 LG 拖尾",造成 α_eff 震荡
  • 真因可能与 frame-level 重构正交,frame-level 后 jitter 可能仍存在
  • 需要进一步 trace 拆解 multi-LG 完成时刻分布才能确认

对方案 C 的影响

ISSUE-018 当前继续走方案 C(frame-level 重构),但重新校准目标

  • 主要目标:spec 对齐(PAXI SUE2.0 UserGuide §2.1.1 Flit Rules 契约)
  • 次要目标:jitter 缓解(不再作为验收 KPI,因为诊断显示 frame-level 未必能消除)

frame-level 重构进度跟踪在 docs/plans/2026-05-12-g5-frame-level-event-refactor.mdplan §目标已同步去除 "α_eff 稳定到 0.30±0.05" 兜底要求

jitter 残余问题在 frame-level 重构完成后单独追踪(必要时开新 ISSUE-020 跟 multi-LG 调度散布)。


第三轮诊断(2026-05-12,frame-level 重构后)

frame-level 重构 (commit bc2a716) 完成后重跑 scripts/debug_g5_m_sweep.py:α_eff 在 0.27~0.73 μs 之间继续震荡,与重构前的范围完全相同。验证了第二轮诊断的预判:frame-level 重构对齐了 PAXI spec,但未消除 jitter。

多变量诊断矩阵

scripts/debug_jitter_v2.py 同时控制 num_link_groupscdma_units

配置α 范围 (μs)α 极差解读
1 unit, 1 LG-0.84 ~ +0.090.93单调(带宽不足占主导,无 jitter)
1 unit, 8 LG2.05 ~ 8.126.07单调(仍无 jitter,但单 unit 提交 OST 限制)
8 unit, 1 LG-0.84 ~ +0.090.93完全消除 jitter(与 1u-1LG 几乎相同)
8 unit, 8 LG0.28 ~ 0.730.45baseline,已知 jitter

@tbl-issue-018-diag2 多变量诊断矩阵

关键证伪:1 LG 配置下 jitter 完全消失,8 LG 才表现 jitter。multi-Unit 本身不是根因,真因在 multi-LG 路径

Wire 带宽不是 jitter 主因

scripts/debug_inf_bw.py 把 C2C bandwidth 从 400 GB/s 调到 40 000 GB/s(100×):

M (KB)G5@400 (μs)G5@40000 (μs)Δ (ns)
5121.4571.4543
5761.1431.08954
10242.1212.1183
11801.9551.87481

@tbl-issue-018-diag-bw c2c 带宽 100x 对照

100× 带宽后 jitter 极差从 1.249 → 1.252,几乎不变。证伪 "PhyLink 串行化是 jitter 主因" 的假设。

真因定位:仿真器内部 ACK drain 时间

scripts/debug_recv_path.py 比较 multi_chip.kernel.total_sim_time_ns(仿真结束)vs max(cdma_unit.last_done_ns)(所有 unit transaction 完成最大值):

M (KB)frames/unitmod 8total_sim (ns)cdma_max (ns)gap (ns)
25644872551321
480801393775618
512801457807650
576911143871272
6401021256935321
96015716591255404
100016020571295762
102416021211319802
110018218731395478
118019319551475480
150024027211795926

@tbl-issue-018-diag-gap total_sim vs cdma_max 时间差

强规律

  • cdma_max 单调递增(无 jitter)—— 反映真实 critical path
  • gap 跳变frames_per_unit % 8 == 0 时 gap 跳高 200~500 ns
    • frames=8 → 9 时 gap 跳跃 -378 ns
    • frames=16 → 15 时 gap 跳跃 -398 ns
    • frames=24 → 19 时 gap 跳跃 -446 ns

每次 frames/unit 跨过 8 的倍数边界,gap 跳变约 400 ns。

根因机制(已定位)

comm_primitive_pipeline.py:70multi_chip.kernel.total_sim_time_ns 作为通信延迟:

sim_time_ns = stats.get("multi_chip.kernel.total_sim_time_ns")

total_sim_time_ns 不是"通信完成时刻",是最后一个 simulation event 的时间戳(包括 CDMA transaction 完成之后的 ACK MERGE poll 残余事件、credit 返还事件、retry timer arm 等)。

当 8 LG 在最后一帧完全同步完成(frames/unit % 8 == 0)时:

  1. 8 LG 同时进入 RX 端 ACK MERGE poll 队列
  2. ACK 返回 chip0 后通过 RSP VC 串行化(轻微贡献)
  3. 8 个 retry_timer 同步 arm(500ms timeout)
  4. credit 返还事件链 + tcredit 反向通信路径
  5. 这些事件全部串行 drain 到 simulation queue 末尾,造成 ~400 ns 额外尾巴

而 frames/unit % 8 != 0 时,LG 间最后一帧错开完成,drain 事件分散,每个事件单独 drain 不集中,gap 小。

修复方向(备选)

方案描述优点缺点
P1comm_primitive_pipeline._build_comm_only_result 改用 max(cdma_unit.last_done_ns) 代替 total_sim_time_ns 作为通信延迟改一行 Python,jitter 立即消失,与真实硬件 critical path 对齐改变 G5 通信延迟语义,需所有 caller 复测;ACK drain 不计入是否符合实际硬件行为有待 spec 确认
P2仿真 kernel 增加"通信完成事件"标记,total_sim 只到该事件为止;drain 残余事件不算语义清晰需要修改 Rust SimKernel,涉及面大
P3接收侧 ACK MERGE / credit return / retry timer 事件不进 kernel 总时间统计治本需要分类事件,区分"应用层"和"内部"
P4维持现状,仅文档说明(已采用方案 A)不改代码用户/前端看到的延迟仍有 jitter

推荐方案

推荐 P1

  1. cdma_unit.last_done_ns 是 PAXI on_remote_done 时间戳,对应 CHS 模式下应用层认为 transaction 完成的时刻(与 SG2262 spec 中 CHS = post-write early-resp 语义一致)
  2. ACK MERGE poll 残余事件是仿真器内部 drain,不影响真实芯片的应用进度
  3. 改动局部(comm_primitive_pipeline.py 一处),易于回滚
  4. 对 N≥4 多步通信场景:cdma_max 仍然是 max across all units,反映 critical path(不影响 pipeline)

验证:用 P1 后重跑 sweep,预期 α_eff 极差 < 0.05 μs,cdma_max 与 Math 模型偏差稳定。

遗留问题(P1 之后)

  • 多步通信场景下 cdma_max 与 total_sim 的差异行为需要验证(N=4 ring 是否仍 ACK drain 滞后)
  • 对 Math 模型 alpha (startup) 的对齐:cdma_max 已不含 ACK 路径,可能 cdma_max 表示的 α 略小于 Math 的 0.30 μs
  • 是否需要新开 ISSUE-020 跟踪"仿真器事件 drain 语义"作为独立改造

第四轮诊断(2026-05-13,P1 修复回滚)

实施 P1 后跑 TPS186 baseline 发现 G5 延迟显著低于 Math(new/Math ≈ 0.5x0.7x,且数值约等于 CDMA datapath 释放时刻),与 ISSUE-016 时观察到的 0.881.25x 范围(基于 total_sim_time)完全不一致。复核 spec 后定位 P1 的根本误解:

spec 依据docs/specs/G5仿真建模/G5-CDMA建模设计规格.md v1.2.0 §sync_id 更新时机 表:

指令CHS 模式完成时机CFS 模式完成时机
TransferCdmaLocalComplete (datapath_end + 5ns)DataArrived (远端 ACK)
SendDataArrived (远端 ACK)DataArrived (远端 ACK)

helpers.rs:5,24,40,78,136,167 显示 Ring AG/RS expand 用的是 CDMAOpType::Transfer(不是 Send)。代码链路 multi_chip.rs:193-199 CdmaLocalCompleteon_remote_done 设置 last_done_ns

结论:CHS 模式 Transfer 下 last_done_ns 设置在 sender CDMA datapath 释放(数据交给 PAXI)时刻,不包含

  • wire transfer 传输时间(数据从 sender PAXI → receiver)
  • RX 端 ACK MERGE 累计 + ACK 返回路径
  • DataArrived 到 sender 的真正 application-visible 完成

P1 用 max(last_done_ns) 把以上时间全部当成 housekeeping 砍掉,砍掉的是真实通信传输时间,不是仿真器噪声。

数值验证:M=1.125 MB N=2 AG,per-chip wire = M/2 = 0.5625 MB,每 chip 8 unit 并行注入,每 unit ≈ 0.07 MB / 64 GB/s = 1.099 μs + CDMA startup 290 ns + 5 ns ≈ 1.394 μs。P1 后 G5 = 1.447 μs ← 完美对应 sender CdmaLocalComplete 时刻,没有计入任何 wire transfer + ACK 路径。

P1 已回滚(2026-05-13),恢复使用 kernel.total_sim_time_ns 作为通信延迟。


重新审视:震荡来源 vs application-visible 完成时刻

回滚后重新思考问题分层:

A. 震荡来源(业界证据 + 物理推导):

  • α 物理来源 = DDR R/W + NoC + PHY serialize,与 M 无关。真实硬件 fixed-algorithm jitter < 50 ns(NCCL arxiv 2507.04786 "variance is very low")
  • 仿真器观察到的 200~500 ns 锯齿主要是 multi-LG 在 frames/unit % 8 == 0 时仿真器内部同步推进(缺失真实硬件 PHY clock skew / router queue jitter)→ 下游事件爆发式调度

B. application-visible 完成时刻的真值

  • 既不是 last_done_ns (CHS Transfer 太早 — 只到 sender datapath 释放)
  • 也不一定是 total_sim_time_ns (可能太晚 — 含 sender 完成后的真正 housekeeping events)
  • 真值 ≈ receiver 收到全部数据的时刻(即 RX 端最后一个 packet receive_packet 完成时)

C. 当前 total_sim_time_ns 的真实组成

  • sender CdmaLocalComplete (~1.4 μs for M=1.125MB AG)
    • wire transfer + ACK MERGE + ACK 返回 sender
    • DataArrived event 处理
    • 各种 housekeeping (CdmaWake/RcLinkWake/CreditReturn drain)

ISSUE-016 时基于 total_sim_time_ns 跑出 G5/Math ≈ 1.0x,说明 total_sim_time_ns 数值上接近 application-visible 真值(housekeeping 量级可能小于估计)。


第五轮诊断(2026-05-13,定位 PAXI LG 调度 Bug)

P1 回滚后重新审视 total_sim_time_ns 的语义。trace 验证它 = max(DataArrived 时刻) = sender 收到最后一个 ACK 的时刻 = application-visible 完成时刻,没有 housekeeping drain

那么 ISSUE-018 报告的 200~500 ns 震荡到底来自哪里?

反物理证据

固定算法 N=2 Ring AG,扫描 M:

M (KB)per-unit packetsframes/unittot_sim (ns)现象
512328145716 cmd 错开 (跨度 577 ns)
576369114316 cmd 同步 (跨度 2 ns)
102464162121错开 (跨度 553 ns)

M=576 比 M=512 完成早 314 ns,但 M=576 多 24 个 packet × 3.44 ns/packet = 多 82 ns 真实 wire time。物理上不可能 M 变大延迟变小——这是仿真器的反物理建模 bug。

Trace 数据:LG 分配的周期共振

scripts/debug_p1_validation.py 加 RcFrameDone / SUBMIT / AckArrived debug print,trace t=290 chip=0 8 个 unit 的 frame_seq=0 分配:

M=512 (frames/unit=8):8 个 unit 的 frame_seq=0 全部分配到 lg=0

[DBG-SUBMIT] t=290 chip=0 lg=0 txn=0 frame_seq=0 ...
[DBG-SUBMIT] t=290 chip=0 lg=0 txn=1 frame_seq=0 ...
[DBG-SUBMIT] t=290 chip=0 lg=0 txn=2 frame_seq=0 ...
... (8 个 unit 全部 lg=0)

M=576 (frames/unit=9):8 个 unit 的 frame_seq=0 分散到 lg=0~7

[DBG-SUBMIT] t=290 chip=0 lg=0 txn=0 frame_seq=0 ...
[DBG-SUBMIT] t=290 chip=0 lg=1 txn=1 frame_seq=0 ...
[DBG-SUBMIT] t=290 chip=0 lg=2 txn=2 frame_seq=0 ...
... (8 个 unit 散到 lg=0~7)

根因机制

paxi.rs::PAXIBridge 用 chip-level shared lg_rr_counter,每次 segment submit 时 counter = (counter + 1) % num_link_groups

  • 每 unit submit 的 frame 数 % num_link_groups == 0(M=512: 8 frames/unit, num_lg=8),每 unit 结束时 counter 恰好转回起点
  • 所有 unit 的 frame_seq=k 全部落到同一 LG_k
  • 叠加 CDMA 注入门控阶梯 earliest_ready_ns(每 segment 间隔 MPS / 注入带宽 = 4096/64 = 64 ns)
  • LG_(N_LG-1) 集中接收所有 unit 的最后一帧,起跑线被推后 (N_LG-1) × 64 ns = 448 ns,单独决定 critical path

frames/unit 不整除 num_link_groups 时,counter 每轮偏移一格,frame 在 LG 上 cross-unit 打散。

完整设计原理(频谱分析、phase lock 数学模型、3 相电网类比、业界 ECMP/RSS/NVLink 对照)见 G5-RC-Link 传输层设计规格 v1.4.0 §为什么 hash 优于 round-robin

硬件 spec 依据

SG2262 C2C 方案明确:

"多个 c2c Link 之间做 ITLV (Hash),从而分散带宽" "同 src macid + 同 dst macid + 同 hash value 时,交换机路径相同且严格保序"

硬件 spec 要求 hash-based ITLV,G5 实现的 chip-level round-robin counter 违反 spec。这是 ISSUE-016 修复 LG 不均衡时引入的副作用(当时为绕开 pick_least_busy_lg + try_arbitrate 互相干扰的 bug 改成纯 RR,但没对齐硬件 spec)。


解决方案(已采用,已修复)

修复:PAXI LG 分配从 chip-level round-robin counter 改为 hash(txn_id, frame_seq, qp_id) % num_link_groups,使用 splitmix64 雪崩 hash。

Spec 改动

文件改动
docs/specs/G5仿真建模/G5-RC-Link传输层设计规格.md v1.3.1 → v1.4.0§ITLV 分发机制 默认策略改为 hash_itlv,新增子段 §为什么 hash 优于 round-robin(设计原理)含频谱分析 + phase lock 数学模型 + 业界对照

代码改动

文件改动
perfmodel/evaluation/g5/src/tier6/paxi.rsmix64 + hash_lg splitmix64 实现;submitfeed_rc_link 中的 closure 用 hash 替代 lg_rr_counter;移除 lg_rr_counter 字段
perfmodel/evaluation/g5/src/tier6/paxi_core.rssubmit / drain_pending / create_segments 的 closure 签名 FnMut() -> u8FnMut(u64, u32, u16) -> u8,传入 (txn_id, frame_seq, qp_id)
perfmodel/evaluation/g5/src/tier6/paxi.rs teststest_least_busy_lg_dispatch 改名 test_hash_lg_dispatch,断言反映 hash 非完全均匀但应打散到 ≥2 LGs

修复效果

反物理消失(M sweep tot_sim 完全单调):

M (KB)旧 round-robin新 hash
2568721034
48013931393
51214571434
5761143 ← 反物理跌1502
64012561638
100020572114
102421212114
11001873 ← 反物理跌2132
118019552250

@tbl-issue-018-fix-monotonic ISSUE-018 hash-based ITLV 修复前后 M sweep 对比

TPS186 baseline 周期共振虚高/虚低消除

Case旧 G5新 G5变化
MLA RS @ 1 MB2.471 μs2.114 μs-357 ns(之前周期共振虚高)
DSA topk_AG @ 32 KB0.763 μs0.483 μs-280 ns(同样虚高)
MLA AG @ 1.125 MB2.293 μs2.250 μs-43 ns
Dense AR @ 0.4375 MB1.923 μs2.054 μs+131 ns

测试:Rust 212 passed / Python 23 passed

遗留问题(已不在本 ISSUE 范围)

  1. CHS Transfer 完成时刻语义:CHS 模式 Transfer 的 last_done_ns 设在 CdmaLocalComplete(sender datapath 释放),不含 wire transfer + ACK 路径。若需测量"receiver 看到全部数据"的精确时刻,需在 Rust kernel RX 端加 stats 字段。当前 kernel.total_sim_time_ns 在 N=2 Ring AG 场景下 = max(DataArrived) ≈ sender 收到 ACK 时刻 ≈ application-visible 完成时刻,作为代理可用。视后续需求决定是否开新 ISSUE。
  2. LLM pipeline adapter.py:144total_sim_time_ns 兜底 SimRecord(ISSUE-010 修复路径),未受 LG 调度 bug 影响。
  3. 微抖动(< 50 ns):hash 后仍存在的统计性碰撞导致的微小 jitter,与真实硬件 PHY jitter 量级相当,作为已知 limitation 接受。