跳到主要内容

ISSUE-024: qp_id 与 thread_id 强绑定导致跨算法 hash 不一致

发现日期:2026-05-14 状态:Resolved (spec v1.4.1 + Task 1-5 实施完成,2026-05-14) 类型:spec 设计偏差 + 仿真精度问题 关联:ISSUE-018 (hash-based ITLV), ISSUE-019/020 (AR 虚假 pipeline 修复)


现象

N=2 同物理通信模式下,不同 AllReduce 算法的 latency 不一致:

算法N=2 AR 64KBN=2 AR 1MB与 Ring 差异 (1MB)
Ring1.001us4.106usbaseline
HD0.944us3.624us-482ns (12%)
DBT1.620us6.351us+55%

理论上 N=2 = 单对芯片交换数据,所有算法物理过程相同,latency 应一致

实测差异源自 multi-LG hash ITLV 在不同 expand 算法下落到不同 LG,因 G5 用 thread_id 作为 hash 输入之一,而 expand 路径 thread_id 分配方案不一致。


根因分析

G5 当前 hash 实现

perfmodel/evaluation/g5/src/top/event_handlers.rs:83:

let qp_id = cmd.thread_id as u16;

perfmodel/evaluation/g5/src/tier6/paxi.rs:29-34:

fn hash_lg(txn_id: u64, frame_seq: u32, qp_id: u16, num_lg: u32) -> u8 {
let combined = txn_id ^ ((frame_seq as u64).wrapping_mul(...)) ^ ((qp_id as u64) << 48);
(mix64(combined) % num_lg as u64) as u8
}

G5 spec (G5-RC-Link 传输层设计规格.md L183) 明文规定:

QP ID 映射:qp_id = CDMA 线程的全局 thread_id

thread_id 在不同 expand 路径下的不一致

Expand 路径thread_id 分配 (chip_index=0/1)
expand_ring_steps (helpers.rs:103-104)local_thread = i % tpc (chip 0 → 0, chip 1 → 1)
emit_pair_transfer (helpers.rs:30,48)硬编码 thread_id: 0 (chip 0/1 都用 0)

替换 channel 后:

  • Ring chip 1 ch=N: thread = 1 + N*16
  • HD/RD chip 1 ch=N: thread = 0 + N*16

同一物理 flow (chip 1 ch=N → chip 0) 在不同算法下 qp_id 差 1 → hash 输出不同 → 落到不同 LG → 负载分布不同 → 完成时间差。

验证

G5_DEBUG=1 跑 N=2 AG 1MB:

  • Ring:最晚 DataArrived cmd=10 @ t=1906,最晚 A4SMsgArrived @ t=1911
  • RD:最晚 DataArrived @ t=1807 (无 trailing RMS)
  • 差 99ns 源自相同的 16 个 Transfer 因 qp_id 不同落到不同 LG, 不是 trailing RMS 协议开销 (那只占 5ns)

Spec 调查

SG2262 原始硬件 spec

SG2262 C2C方案.docx (本地路径见 memory reference_hardware_specs.md):

  • L83: "支持多个 c2c Link 之间做 ITLV(Hash),从而分散带宽"
  • L116: "同 src macid,同 dst macid, 同 hash value 时,交换机路径相同,且交换机交换严格保序"
  • L241: "计算 itlv 算法,并根据 L1_port_num 选择 c2c port" (算法细节缺失)
  • L255 + image22 (RNSAM): NoC 内部用 Address[43:0] 做 hash 选 d2d group (但这是 NoC 路由,不是 c2c link ITLV)
  • AXI awuser 字段表 (Table T10):chipid / dieid / ch_sel / are_opcode / cps_en, 无 thread_id 字段 — 硬件 c2c MAC 报文头不携带 thread_id

2262 CDMA spec v2.2.docx:

  • L105: hash 只在 icache 替换中提到 (addr+threadid),与 c2c ITLV 无关
  • 全文无 ITLV / LG 分发算法描述

PAXI 原始 spec

RCLINK_AFH_SPEC_v2.4.pdf:

  • P5L20: "使用 qp_id 的低位作为 bank_id,支持非幂次 QP_NUM 配置"
  • P32L2: "TYPE1_REQ 通过参数配置划分为 1/2/4 个 BANK,按 QPID 最低 2bit 进行区分"
  • P37L30 (LITE mode): Source_qpid = {XPU_ID, BANK} — XPU_ID 是上游模块标识 (CDMA/GDMA/TPU_SCALAR), BANK 是 VC bank
  • PAXI 是单 link 的协议层,不涉及多 LG/ITLV 分发 — 多 LG 是上层 (RC Link 多实例) 的事

关键差异

字段SG2262 + PAXI 硬件 specG5 当前 spec
qpid 高位语义XPU_ID (上游模块 ID,如 CDMA 单元号)thread_id (CDMA 内部线程号)
qpid 低位VC bank (PAXI spec 明文)thread_id 低位 (无意义)
硬件可见性报头 MAC_SA 高位 + Traffic Classthread_id 不在 c2c 报头

RoCEv2 ECMP

  • 5-tuple hash: src/dst MAC + src/dst IP + src/dst UDP port
  • QP 信息编码进 source UDP port (每 QP 用不同 src port, dst port 固定 4791)
  • 同 QP 报文走同路径 (保序)
  • AI/ML 训练网络 (Juniper) 增强:把 destination QPN 显式加入 hash 提升熵 (5-tuple 在 RDMA 场景熵不足)

InfiniBand 多端口 HCA

  • Multi-port HCA 各端口用 GID 分配做 RR/hash 负载均衡
  • HCA 多端口间按 dst IP/GID hash 分配 VF

NVLink/NVSwitch

  • 不用静态 hash,用 congestion-aware adaptive routing (看队列深度)
  • 软件层 (CUDA/NCCL) 透明感知 NVSwitch 拓扑

共识

业界 hash 输入用 transport 层连接标识 (QPN, source UDP port),这些是报文头可见字段,与软件内部线程号无关。


推荐修复方向

方案 A (推荐):重新定义 qp_id 编码,对齐硬件 + PAXI spec

// 提议: qp_id = (cdma_id << 2) | vc_bank
let qp_id = ((cmd.cdma_id as u16) << 2) | (vc_bank as u16);

含义:

  • 高位:cdma_id (per-chip 0..7,对应硬件 CDMA 单元 = PAXI spec 的 XPU_ID)
  • 低 2 位:vc_bank (对应 PAXI spec qpid 低位 = VC bank)

效果:

  1. 同一物理 cdma 发的 flow 共享 qp_id 高位 → 同 flow 走同 LG (符合硬件 spec L116 保序约束)
  2. 不同 cdma 之间用 qp_id 高位差异散布到不同 LG (类似 RoCEv2 用 source UDP port)
  3. 与 expand 层 thread_id 分配解耦 → 不同算法物理 flow 一致 → N=2 算法等价性恢复
  4. 符合 PAXI spec P5/P32/P37 "qpid 低位 = bank" 约定

需要修改:

  • event_handlers.rs:83/111/130 (3 处 let qp_id = cmd.thread_id as u16)
  • G5-RC-Link 传输层设计规格.md L183 "qp_id = thread_id" → 新定义
  • 相关测试 (paxi.rs:test_hash_lg_dispatch 等)
  • comm-primitive.md 更新对齐效果

方案 B (替代):短期 emit_pair_transfer 与 expand_ring_steps 对齐 thread 分配

emit_pair_transfer 也用 chip_idx (而非硬编码 0) 作 thread_id 基,使 Ring/HD/RD/RH/DBT 走同 qp_id。

仅修 expand 层,不改 spec/hash 实现。

只解决 N=2 表面症状,没解决根本问题:thread_id 不该作为 qp_id (硬件不可见,与协议层语义不符)。

方案 C (长期):完全弃用 qp_id 当 hash 输入

PAXI spec 没说 hash 用 qp_id。可考虑:

  • Hash 用 (src_chip, dst_chip, cdma_id) — 完全符合硬件 c2c MAC 可见字段
  • 或 hash 用 Address bits (类似 RNSAM)
  • qp_id 仍按 PAXI spec {XPU_ID, BANK} 编码,但不参与 LG hash,只用于 PSN/CC/VC bank 路由

影响范围

修复后预期变化:

  • N=2 各算法 latency 收敛到 ±5ns 协议层差异 (vs 当前 50~500ns)
  • Ring/HD 在所有 N 下 hash 结果稳定 (不再随 expand 实现细节变)
  • comm-primitive.md baseline 数值需重测

不影响:

  • 实际 Math vs G5 总体对齐 (~1.1x 在合理范围)
  • 多 LG 并行/ITLV 整体机制
  • ISSUE-019/020 已完成的 AR 虚假 pipeline 修复

优先级

中等。N=2 是 TP 通信主要场景,算法等价性对 baseline 文档可信度有影响,但与 Math 对齐已在可接受范围。

可在 Phase 2 P3 (仲裁与流水化) 完成后单独立 plan 实施。或与方案 A 的 spec 修订一起做。


后续 action

  1. 更新 G5-RC-Link 传输层设计规格 §QP ID 映射 (移除 thread_id 强绑定,改用 cdma_id+bank)
  2. 写 plan 实施 event_handlers.rs 改动
  3. 重跑 torus + tps186 baseline,验证 N=2 算法等价性
  4. 更新 comm-primitive.md 数据

Implementation Notes (2026-05-14)

完成的改动

  • event_handlers.rs:新增 encode_qp_id() helper + QP_BANK_W 常量,三处 let qp_id = cmd.thread_id as u16 改为 encode_qp_id(cmd.cdma_id)
  • G5-RC-Link 传输层设计规格.md v1.4.1: §PSN 管理 + §VC 仲裁 + §ITLV 分发机制 三处契约改写,新增公式 eq:rc-qp-id-encoding, Goals G5 描述更新
  • collective/expand.rs:tests:新增 test_cross_algo_cdma_id_stable_n2 端到端测试覆盖 Ring/HD/RD/RH 6 个算法组合

验证结果 (N=2 各算法 latency 收敛)

op修复前 max-min修复后 max-min收敛幅度
N=2 AR 1MB482ns10ns48×
N=2 AG 1MB104ns5ns20×
N=2 RS 1MB104ns5ns20×

DBT N=2 不参与对比 (4 sequential edges × M/2 物理流量 2× Ring)。

G5/Math 对齐改善 (smoke_tps186_baseline)

原语修复前 G5/Math修复后 G5/Math
Dense_MLP AR 0.4375MB1.11x1.06x
MLA AG 1.125MB1.06x1.00x
MLA RS 1.0MB1.05x1.01x
MLA AR 0.4375MB1.11x1.06x
DSA topk_AG 32KB1.06x1.07x

回归检查

  • ring_2port speedup vs ring: N=4 1.52x / N=8 1.73x / N=16 1.86x (与修复前 1.48/1.76/1.88x 在 ±2% 内)
  • cargo test --lib --release: 247 passed; 0 failed (修复前 246 + 新增 cross-algo 1)
  • torus 576 rows 全量重写,无算法 panic

已知偏离 plan

  • Plan Task 4 Step 6 "LG 利用率分布偏差 < 20%" 阈值过严:实测 AR 1MB chip 0 LG 分布 max-min/mean ≈ 79%。这是 hash-based ITLV 本质特性 (hash 不保证 perfect 均衡),修复前后该指标无显著变化,不影响 AR/AG/RS 宏观 ratio 与 Math 对齐 (实际 ratio 反而改善)。建议下次修订 plan 时把 "LG 分布 < 20%" 改为"修复前后偏差变化 < 10%" 类相对指标。

后续 TODO (非本 issue 范围)

  • vc_bank 当前用 cdma_id & 3 简化策略,长期可考虑暴露为 cmd 字段 (按 traffic class 由 expand 层指定)
  • 多 XPU 接入 (GDMA / TPU_SCALAR) 时需在 schedule_via_paxi 增加 XPU 类型分支,各自的 XPU_ID 用全局 namespace 编号

后续修复 (2026-05-14, plan 2026-05-14-pair-transfer-msg-path.md)

ISSUE-024 完成后 N=2 各算法仍残留 5-10ns 差异,源自 emit_pair_transfercmd_id_dep_remote + sender-side mark 模拟 SG2262 不支持的 "CDMA_write 自动 sideband",违反 G5-CDMA spec v1.3.2 §跨 chip 数据到达依赖 L296.

修复:让 emit_pair_transfer 与 expand_ring_steps 走相同的 spec L294 "write + 显式 msg 指令" 路径 — emit Transfer + RemoteMsgSend (cmd_id_dep_remote=(dst, T.id)) + (后续 round 前置 MsgWait).

涉及文件:helpers.rs:emit_pair_transfer 重写 + 4 个 caller (HD/RD/RH/DBT) 传 round_idx 适配 + 11 个 cmd_count 测试断言更新。

N=2 各算法 latency 终态 (修复后)

opsizeringring_2portHD/RD/RHmax-min
AR64KB1.0011.0011.0010ns
AR1MB3.6813.6813.6810ns
AG1MB1.8121.8121.8120ns
RS1MB1.8121.8121.8120ns

ring / ring_2port / HD/RD/RH 在 N=2 下 latency 完全相同 (max-min = 0ns)。DBT N=2 因 12 transfer vs others 4 transfer 物理流量差异例外。

N≥4 影响

  • ring_2port speedup vs ring: N=4 1.52x / N=8 1.73x / N=16 1.86x 完全不变 (Ring 路径不通过 pair_transfer)
  • HD N=16 1MB AR: 7.56us → 10.53us (修复前 0.42× ring → 修复后 0.56× ring),HD 优势从 58% 缩到 44%,因新增 msg 同步协议成本,物理更准确
  • Smoke G5/Math 比例不变 (Ring/Math 不受影响)

cargo test --lib --release: 247 passed (含 11 个 cmd_count 测试断言更新)

Task 0 对照实验结论

临时移除 event_handlers.rs sender-side mark_remote_cmd_done 后,Ring AR sendq 残留 s=1/4 (3/4 cmds 卡在 dep_remote 永不满足),sim kernel 因无更多事件提前空闲退出报错误时间。反证 sender-side mark 是 Ring RMS 必需 (PAXI ACK 路径近似),严格意义违反 spec L296,视为 simulation 简化,后续 issue 替换为本地 PAXI b-resp 模型。