Switch 交换机模型集成验证
概述
本文通过 G5 事件驱动仿真器,验证 Switch 交换机模型在真实通信场景下的行为正确性。Switch 建模了 VOQ(Virtual Output Queue)+ iSLIP 调度 + 动态阈值准入控制 + ECN RED 概率标记,是多芯片仿真中 Clos/Fat-Tree 拓扑的核心组件。
此前 Switch 仅有 6 个 Rust 单元测试(基本入队/调度、ECN 阈值、iSLIP 轮转)和 1 个 Python 侧 E2E 测试(4-chip Clos AllReduce),覆盖的都是功能正确性的最小集合。参考 PAXI 模块的验证经验——单元测试全部通过但实际通信场景中暴露了大量问题——本次设计了 3 类共 8 个集成验证场景,重点关注拥塞行为、ECN-DCQCN 反馈闭环、多跳路由延迟和端口映射等在单元测试中无法覆盖的行为。
仿真平台
| 参数 | 值 |
|---|---|
| 芯片 CDMA 带宽 | 450 GB/s |
| C2C 链路带宽 | 400 GB/s |
| C2C 链路延迟 | 0.1 us (100 ns) |
| Switch 转发延迟 | 30 ns |
| Switch 端口带宽 | 400 GB/s |
| Switch 帧大小 | 1406 bytes |
| Switch time slot | 1406 / 400 = 3.515 ns |
| iSLIP 迭代次数 | 2 |
| PAXI MPS | 16384 bytes |
| PAXI max_payload | 8192 bytes |
| PAXI credit_size | 4096 bytes |
| DCQCN cnp_interval_ns | 2,500 (修复后,~3 RTTs) |
| DCQCN timer_interval_ns | 3,000 (修复后,~4 RTTs) |
拓扑配置
- 星形拓扑:所有 chip 通过单个 ToR switch 互联,chip ↔ sw0 双向链路
- Clos 拓扑:chip → ToR → Spine → ToR → chip,两层 switch
- 直连 Ring:chip 间直连(无 switch),作为对照基准
测试代码位置
Rust 测试:perfmodel/evaluation/g5/src/top/multi_chip.rs,#[cfg(test)] 模块中 test_switch_* 和 test_clos_* 系列。
实验 1:Incast 多对一拥塞
实验设计
验证 Switch 在多个发送端竞争同一个 egress 端口时的拥塞行为。这是交换机最基本的竞争场景,在 AllReduce 的 reduce 阶段天然存在。
| 测试 | 配置 | 目标 |
|---|---|---|
test_switch_incast_3_to_1 | 4 chip 星形拓扑,chip 1/2/3 → chip 0,各发送 256 KB | 3 流竞争 egress port 0,延迟应 > 2x 单流 |
test_switch_incast_vs_no_contention | 同上,对比单流 (chip 1 → chip 0) | incast 应显著慢于单流 |
实验结果
| 指标 | 值 |
|---|---|
| 单链路理论传输时间 | 256 KB / 400 GB/s = 655.4 ns |
| 单流实测 (chip 1 → chip 0) | 1487.0 ns |
| 3 流 incast 实测 | 2805.0 ns |
| incast / 单流比值 | 1.89x |
| incast / 理论值比值 | 4.28x |
分析
符合预期的部分:
- Incast 确实比单流慢,switch egress 端口竞争产生了可观测的排队延迟
- 单流 1487ns vs 理论 655ns,差异来自 PAXI 协议栈开销(事务建立、credit 协商、分段/重组)+ switch 转发延迟 (30ns) + 双向链路延迟 (2 × 100ns)
异常点:3 流 incast 仅比单流慢 1.89x,而非预期的接近 3x
理论上 3 个流竞争同一个 egress port,端口序列化应使总时间接近 3x 单流。实际只有 1.89x,原因分析:
- iSLIP 每个 time slot 只匹配 1 对端口:每个 tick 只有一个流的包能从 egress 发出,但 time slot 仅 3.5ns,而 PAXI 发包间隔远大于此(~20-50ns),所以 switch 端口竞争窗口很短
- PAXI 流水线效应:3 个发送端的 PAXI 事务建立是并行的,协议开销不累加
- 瓶颈不在 switch:真正的瓶颈可能在 PAXI 发送端的 credit 流控,而非 switch 的 VOQ 排队。DIAG 日志显示
credit_block=0,说明 credit 未成为瓶颈,但tx_busy和no_sendable占了大量 arb_calls - switch time slot 过小:1406/400 = 3.5ns 的 time slot 意味着 switch 处理速度远快于 PAXI 产生包的速度,switch 几乎不会积压
结论:Incast 拥塞建模基本正确,但 switch 在当前参数下不是瓶颈——PAXI 协议栈的发包速率才是限制因素。Switch 的竞争效应被 PAXI 的发包间隔稀释了。
实验 2:ECN-DCQCN 反馈闭环
实验设计
验证 Switch ECN 标记 → PAXI RX 检测 → CNP 生成 → PAXI TX DCQCN 降速 → buffer 利用率下降 → 速率恢复 的完整反馈环路。
| 测试 | 配置 | 目标 |
|---|---|---|
test_switch_ecn_dcqcn_feedback | 2 chip 星形拓扑,buffer=32KB,kmin=0.3,kmax=0.6,发送 1MB | ECN 应触发 DCQCN 降速,仿真完成且比直连慢 |
test_switch_ecn_bidirectional_traffic | 2 chip 星形拓扑,buffer=64KB,双向各发 512KB | 双向流在 switch 竞争,ECN 应在两方向都触发 |
实验结果
| 指标 | 值 |
|---|---|
| 直连 (无 switch) 1MB P2P | 3152.0 ns |
| 经 32KB-buffer switch 1MB P2P | 3465.0 ns |
| switch / 直连比值 | 1.10x |
| 双向 512KB 总延迟 | 2146.0 ns |
| 双向 / 单向理论值比 | 1.64x |
分析
初始发现:ECN-DCQCN 反馈闭环未生效
32KB 的 switch buffer 传输 1MB 数据时,buffer 应被反复打满。按照 PAXI max_payload=8192 bytes,仿真中每个包 payload ~8KB,4 个包就能填满 32KB buffer。1MB 数据需要约 128 个包,但 buffer 只能容纳 4 个。
实际仅比直连慢 10%,DCQCN 降速几乎未生效。调查发现两个根因:
- Switch buffer 未真正拥塞:switch time slot 3.5ns 极快,入队的包在下一个 tick 就被取出。PAXI 发包间隔 (~20-50ns) 远大于 switch 处理速度,buffer 来不及积压到 ECN 阈值
- DCQCN 时间常数与 C2C RTT 严重不匹配:CNP 间隔 50us、恢复定时器 55us,远大于 C2C RTT (~800ns)。整个传输仅 ~3.5us,DCQCN 来不及反应
修复:将 DCQCN 时间常数按 C2C RTT 缩放(参见实验 5 详细说明):
cnp_interval_ns: 50,000 → 2,500 (~3 RTTs)timer_interval_ns: 55,000 → 3,000 (~4 RTTs)
修复后在 32-chip Clos + 小 buffer 场景下成功触发了完整的 ECN-DCQCN 反馈闭环(详见实验 5)。
实验 3:双层 Clos AllReduce
实验设计
验证多跳 switch 路由下的 AllReduce 性能,以及 switch 延迟对整体通信的影响。
| 测试 | 配置 | 目标 |
|---|---|---|
test_clos_allreduce_8_chips | 8 chip,4 chip/ToR,2 ToR + 1 Spine,Ring AllReduce 1MB | 双层 Clos 完成 AllReduce,延迟合理 |
test_clos_vs_direct_allreduce | 4 chip,直连 Ring vs 星形 Switch,AllReduce 512KB | switch 引入的额外延迟应可观测 |
实验结果
| 指标 | 值 |
|---|---|
| 8-chip Clos Ring AllReduce 1MB | 5615.0 ns |
| 理论 Ring AllReduce 时间 | 2×(7/8)×1MB/400 = 4587.5 ns |
| 仿真 / 理论比值 | 1.22x |
| 4-chip 直连 Ring 512KB | 2365.0 ns |
| 4-chip 经 switch 星形 512KB | 2491.0 ns |
| switch / 直连比值 | 1.05x |
分析
8-chip Clos AllReduce (1.22x 理论值)
22% 的开销来源分解:
- PAXI 协议栈开销(事务建立、credit、分段/重组)
- Switch 转发延迟:每个包经过 switch 增加 30ns,跨 ToR 的步骤经过 3 个 switch (ToR + Spine + ToR) 增加 90ns
- 链路传播延迟:每跳 100ns
这个比值与之前无 switch 的 AllReduce 验证结果一致(通常 1.15-1.25x),说明 switch 的额外开销被 PAXI 协议栈开销掩盖了。
Switch vs 直连差异过小 (仅 5%)
这是最值得关注的异常。4-chip Ring AllReduce 有 6 步 (2×(N-1)),每步经 switch 增加至少 30ns 转发延迟 + 100ns 额外链路延迟(chip→switch + switch→chip vs 直连 chip→chip),理论额外开销约 6 × 130ns = 780ns。
但实际只多了 126ns (2491-2365),远小于预期的 780ns。
可能原因:
-
直连也有 100ns 链路延迟:直连 Ring 的链路配置是 450GB/s + 0.15us (150ns),而 switch 链路是 400GB/s + 0.1us (100ns)。经 switch 的路径是两段链路 (chip→sw 100ns + sw→chip 100ns = 200ns),vs 直连一段 150ns,差值只有 50ns/步
-
带宽差异:直连 Ring 链路带宽 450GB/s,switch 链路 400GB/s。512KB / 8192B = 64 个包,每个包在 450GB/s 链路传 ~18.2ns,400GB/s 链路传 ~20.5ns。差异很小
-
Switch 转发延迟 (30ns) 被 pipeline 掩盖:Ring AllReduce 的流水线效应使前一步的尾部包和后一步的头部包重叠传输,switch 的 30ns 延迟在流水线间隙中被隐藏
结论:switch 延迟建模可能是正确的,但由于 switch time slot (3.5ns) 极快、流水线效应强、且测试中直连和 switch 链路参数不完全对等,导致 switch 开销在 AllReduce 中几乎不可见。
实验 4:端口映射正确性
实验设计
验证 handle_switch_ingress 中的端口映射逻辑 ingress_port = src_chip % port_count。当 chip 数 > port 数时,多个 chip 映射到同一个端口,会引入虚假的 HOL blocking。
| 测试 | 配置 | 目标 |
|---|---|---|
test_switch_port_mapping_collision | 8 chip + 4-port switch vs 8 chip + 8-port switch,两组独立 P2P | 端口碰撞应增加延迟 |
实验结果
| 指标 | 值 |
|---|---|
| 无碰撞 (8 端口) | 1157.0 ns |
| 有碰撞 (4 端口) | 1482.0 ns |
| 碰撞 / 无碰撞比值 | 1.28x |
分析
端口碰撞确实产生了 28% 的额外延迟。具体碰撞情况:
- chip 0 和 chip 4 →
ingress_port = 0 % 4 = 0(共享入口端口 0) - chip 1 和 chip 5 →
ingress_port = 1 % 4 = 1(共享入口端口 1) - 出口端口同理碰撞
这是一个设计问题,不是 bug:chip_id % port_count 的映射假设 chip_id 和物理端口之间有模运算关系,但实际拓扑中每条物理链路应对应独立的端口号。正确做法应该是在拓扑配置中显式指定每条链路对应的 switch 端口号,而非运行时用 chip_id 取模。
当 chip 数 ≤ port 数时,当前映射恰好正确(每个 chip 独占一个端口)。但当 chip 数 > port 数时,映射产生虚假碰撞,与真实 switch 行为不符。
实验 5:32-chip Clos 规模验证 + ECN-DCQCN 闭环确认
实验设计
在修复 DCQCN 时间常数后(cnp_interval_ns: 50000→2500, timer_interval_ns: 55000→3000),用 32 芯片 Clos 拓扑验证:(1) 大规模 AllReduce 性能;(2) 通过缩小 buffer 强制触发 ECN,确认 DCQCN 反馈闭环完整生效。
| 测试 | 配置 | 目标 |
|---|---|---|
test_clos_allreduce_32_chips | 32 chip, 4 ToR (8 chip/ToR) + 1 Spine, buffer=256KB, AllReduce 4MB | 大规模 Clos AllReduce 性能基准 |
test_clos_32_chips_small_buffer | 同上但 buffer=16KB, kmin=0.2, kmax=0.5 | 强制触发 ECN,验证 DCQCN 反馈闭环 |
DCQCN 参数修复
原始参数来自数据中心以太网论文(RTT ~10us),未按 C2C 互联 RTT (~800ns) 缩放:
| 参数 | 修复前 | 修复后 | 依据 |
|---|---|---|---|
cnp_interval_ns | 50,000 | 2,500 | ~3 RTTs @ C2C RTT≈800ns |
timer_interval_ns | 55,000 | 3,000 | ~4 RTTs @ C2C RTT≈800ns |
Spec 确认:RCLINK_AFH_SPEC §5.3/§5.9 只定义了 CC_WINDOW 和 CNP MERGE 的硬件机制,DCQCN 时间常数由软件配置,非硬件固定值。
实验结果
| 指标 | 256KB buffer | 16KB buffer |
|---|---|---|
| 仿真时间 | 22,271 ns | 186,684 ns |
| Ring AllReduce 理论时间 | 20,320 ns | 20,320 ns |
| 仿真 / 理论比值 | 1.10x | 9.19x |
| ECN 标记总数 | 0 | 20,288 |
| 丢包总数 | 0 | 11,273 |
| rate_block(每芯片) | 0 | 28~154 次 |
| NAK 重传(每芯片) | 0 | ~420 次 |
分析
256KB buffer(正常场景):1.10x 理论值
32-chip Ring AllReduce 4MB 的理论时间为 2×(31/32)×4MB/400GB/s = 20,320ns。仿真结果 22,271ns (1.10x) 非常接近理论值,10% 开销来自 PAXI 协议栈(事务建立、credit 协商、分段/重组)和 switch 转发延迟。256KB buffer 充裕,无 ECN 触发,无丢包。
16KB buffer(拥塞场景):ECN-DCQCN 完整闭环确认
16KB buffer 在 32-chip AllReduce 中严重不足,成功触发了完整的反馈环路:
- ECN 标记:所有 switch 共产生 20,288 次 ECN 标记,确认 switch RED 概率标记正常工作
- CNP 生成:RX 收到 ECN 标记后生成 CNP 回复(cnp_interval_ns=2500 限流生效)
- DCQCN 降速:TX 收到 CNP 后触发 rate_block,每芯片 28~154 次降速
- 丢包与重传:11,273 次丢包触发 Go-Back-N 重传,每芯片约 420 次 NAK 重传
- 仿真完成:尽管严重拥塞,所有数据最终传输完成,仿真正常结束
16KB buffer 过于激进(大量丢包),实际部署应使用 64KB~256KB 之间的 buffer。但此测试成功证明了 ECN→CNP→DCQCN 降速→重传恢复 的端到端反馈闭环在参数修复后完全正常工作。
总结:发现的问题
确认的 bug / 设计问题
| # | 严重程度 | 模块 | 描述 | 状态 |
|---|---|---|---|---|
| 1 | 高 | event_handlers.rs | 端口映射 src_chip % port_count 在 chip 数 > port 数时产生虚假碰撞。已改为拓扑显式指定端口映射 | 已修复 |
| 2 | 中 | ECN-DCQCN 闭环 | Switch time slot (3.5ns) 远快于 PAXI 发包间隔,buffer 来不及积压,ECN 在小数据量 + 大 buffer 下不触发。这是正常行为——拥塞场景(小 buffer / 大流量)下 ECN 正常触发 | 非 bug |
| 3 | 中 | DCQCN 参数 | CNP 间隔 50us、恢复定时器 55us 来自数据中心以太网论文,未按 C2C RTT (~800ns) 缩放。已修改为 cnp_interval=2500ns, timer_interval=3000ns | 已修复 |
非 bug 但需关注的现象
| # | 现象 | 说明 | 状态 |
|---|---|---|---|
| 4 | Incast 1.89x vs 预期 3x | 不是 bug,switch 转发速度快于 PAXI 发包速度,瓶颈在 PAXI 协议栈而非 switch | — |
| 5 | Switch vs 直连仅差 5% | 不是 bug,switch 延迟被 Ring AllReduce 流水线效应掩盖,且测试链路参数不完全对等 | — |
| 6 | Switch 统计未导出 | SwitchModel.drops 和 packets_forwarded 没有 dump 到 Stats 中 | 已修复 |
后续建议
修复端口映射— 已完成:改为拓扑显式指定端口映射增加 Switch 统计导出— 已完成:switch drops、packets_forwarded、buffer 峰值、ECN 标记次数已写入 Stats大数据量 ECN-DCQCN 验证— 已完成:32-chip Clos 4MB AllReduce + 小 buffer 场景,确认 ECN-DCQCN 反馈闭环正常工作(实验 5)背压验证— 已完成:16KB buffer 场景触发丢包 (11,273) + Go-Back-N 重传 (~420/chip),端到端恢复正常(实验 5)- 优化 buffer 参数:16KB 丢包过多 (9.19x 理论值),256KB 无拥塞 (1.10x),可探索 64KB~128KB 范围找到 ECN 生效但丢包可控的平衡点