G5 Switch 建模设计规格
版本:1.2.0 状态:Draft 创建日期:2026-04-21 最后更新:2026-06-01 作者:xiang.li 前置:互联通信G5仿真建模设计规格
变更历史
| 版本 | 日期 | 变更说明 |
|---|---|---|
| 1.2.0 | 2026-06-01 | 按 spec 模板重构:H2 全中文 + 9 节重排,新增名词定义与非功能性需求,接口签名/数据结构/字段表下沉附录 C |
| 1.1.0 | 2026-04-21 | 补充硬件流水线抽象、PAXI 帧格式与 ECN 关系、数据结构定义、forward/tick 接口、诊断计数器、事件调度集成、流程图 |
| 1.0.0 | 2026-04-21 | 初版:iSLIP 指针规则、DT 简化公式、优先级二值化、出口序列化 overlap、ECN 标记时机 |
@tbl-spec-switch-01 文档变更历史
概述
Switch 是 G5 仿真中可选的交换机模型,当拓扑中存在 switch 节点时自动创建。本 spec 定义 Switch 的完整设计,覆盖以下七部分:
- VOQ 缓冲结构
- iSLIP 调度算法的指针更新规则
- Dynamic Threshold 准入控制的简化公式
- 优先级分类的二值化设计
- 出口端口序列化的 overlap 行为
- ECN 标记的出队时机
- Switch 与仿真主循环的事件集成机制
Switch 是多芯片拓扑中延迟变化的主要来源(零负载约 250ns,incast 可达数十 μs)。iSLIP 调度细节和 DT 准入控制直接影响拥塞场景下的尾延迟预测。
背景
前置 spec 对 Switch 的描述覆盖了 VOQ + iSLIP + DT + ECN 的基本概念。本 spec 细化前置 spec 的 Switch 概述,并记录与设计文档的差异。以下设计决策与设计文档不一致或未描述:
- iSLIP 指针更新规则:标准 iSLIP 只在第一轮迭代更新指针(去同步化),前置 spec 未明确这一细节
- DT 公式简化:标准 DT 算法(Choudhury-Hahne)含 $N_{\text{active}}$ 除数,本实现与前置 spec 均省略(用 allowed = $\alpha \cdot (B_{\text{cap}} - B_{\text{used}})$ 简化式)
- 优先级二值化:PAXI 行为分析文档 / VLAN PCP 映射描述多级优先级(PCP→4 级),本实现只有两级(3 和 2),与前置 spec 一致
- 出口序列化 overlap:forwarding_latency 与后续 contention 重叠,不是串行叠加
- ECN 标记时机:在出队时标记(非入队时),使用出队前的缓冲占用率
- 硬件流水线到仿真抽象的映射:设计文档定义了 12 级流水线,仿真中抽象为固定 forwarding_latency,但抽象依据未记录
- PAXI 帧格式对 ECN 的约束:ECN 仅在 Standard 格式下可用,仿真中的假设未说明
- Switch 与仿真主循环的事件集成:forward/tick 的完整调用链路和事件调度未描述
名词定义
| 名词 | 定义 | 与易混淆概念的区分 |
|---|---|---|
| VOQ (Virtual Output Queue) | per-(ingress, egress, priority) 独立队列,消除 Head-of-Line 阻塞 | 与输出队列不同:VOQ 在入口侧按出口分队,物理缓冲在入口而非出口 |
| iSLIP | 迭代式 Request-Grant-Accept 匹配调度算法,用指针去同步化逼近 100% 吞吐 | 与单轮 SLIP 不同:iSLIP 多轮迭代,且指针只在第一轮更新 |
| Dynamic Threshold (DT) | 准入控制:单队列可占缓冲随全局剩余缓冲动态变化 | 与静态阈值不同:阈值随 buffer_used 实时变化,不是固定上限 |
| forwarding_latency | 固定转发延迟,抽象 12 级流水线中 Stage 1-10(默认 30ns) | 与序列化延迟不同:不占用出口端口资源,与后续包 contention overlap |
| 出口序列化延迟 | 帧通过出口端口物理发送所需时间 = pkt_bytes / port_bandwidth | 与 forwarding_latency 不同:独占出口端口,决定 port_busy_until |
| ECN RED 标记 | 出队时按缓冲利用率以 RED 概率曲线标记拥塞 | 与入队标记不同:用出队前利用率,时机在 tick() 出队后 |
| SwitchTick | 自驱动的 iSLIP 调度事件,间隔 = time_slot_ns | 与固定周期轮询不同:有包才调度,VOQ 清空即停 |
| time_slot | iSLIP 调度的最小时间粒度 = frame_size_bytes / port_bandwidth | 与 forwarding_latency 无关,仅决定 tick 间隔 |
| 优先级二值化 | priority=3(零字节控制消息)/ priority=2(数据),仅两级 | 与 PAXI 行为分析文档 / VLAN PCP 映射(4 级)不同:无 Low(1) 流量 |
| CBFC / PFC | CBFC 端到端 credit 流控(对 Switch 透明);PFC 逐跳 PAUSE 流控(需 Switch 收发) | 仿真用 CBFC,PFC 未实现 |
目标与非目标
目标:
- G1:精确定义 iSLIP 调度的指针更新规则和迭代行为
- G2:定义 DT 准入控制的实际公式(与标准 DT 算法的差异)
- G3:明确优先级分类的二值化设计及其原因
- G4:定义出口序列化的 overlap 行为和时间计算
- G5:定义 ECN 标记的时机和概率计算
- G6:定义 SwitchTick 的自驱动调度机制
- G7:说明硬件 12 级流水线到仿真固定延迟的抽象映射
- G8:明确 PAXI 帧格式对 Switch 功能(ECN/QoS)的约束
- G9:定义 Switch 与仿真事件循环的完整集成机制
- G10:定义完整的数据结构、接口签名和诊断计数器
非目标:
- Switch 内部 12 级流水线的 per-stage 建模(仿真中抽象为固定 forwarding_latency)
- DWRR 出口调度(设计文档提及但未实现)
- PFC watchdog timer(需要 Switch→Chip PAUSE 帧,已延后)
- 多优先级 iSLIP(当前所有优先级在同一匹配池中调度)
- 多报文格式支持(仿真中假设 Standard 格式,固定 header_overhead)
用例说明
走一遍一个数据包经过 Switch 的完整流程。假设 Chip 0 发出的数据包到达 Switch 的 ingress port 2,目标 Chip 1 连接在 egress port 5:
入队成功后,若无 pending tick 则调度 SwitchTick;SwitchTick 触发 iSLIP 调度,匹配成功的 VOQ 出队、ECN 标记、计算出口延迟,生成 SwitchForwardResult 回到事件循环,再由 C2CNetwork 转发到下一跳。
详细设计
硬件流水线与仿真抽象
真实交换机内部有 12 级处理流水线(500MHz 时钟,2ns/cycle)。仿真将 Stage 1-10(PHY_RX 到 OUTPUT_SCHEDULE)抽象为固定 forwarding_latency_ns(默认 30ns),Stage 12 (PHY_TX) 建模为出口序列化延迟,排队延迟通过 VOQ + iSLIP 动态建模。这三部分的组合覆盖了真实交换机的全部延迟来源。完整流水线分级见附录 A。
PAXI 帧格式与 Switch 功能约束
PAXI 协议支持四种帧格式,不同格式对 Switch 功能有直接影响:仅 Standard 格式(有 IP 头)支持 ECN,AFH 系列格式不支持。完整格式对比见附录 A。
仿真假设:G5 仿真假设使用 Standard 格式(有 IP 头),因此 ECN 标记功能可用。frame_size_bytes 默认值 1406B 即对应 Standard 格式的最大帧。如果使用 AFH 格式,Switch 的 ECN 标记将无效,需要依赖 CBFC 端到端流控(对 Switch 透明)或 PFC 逐跳流控。
CBFC vs PFC:CBFC 是端到端 credit 流控,完全不经过 Switch,Switch 只做透明转发。PFC 是逐跳流控,需要 Switch 主动收发 PAUSE 帧。仿真中使用 CBFC(对 Switch 透明),PFC 未实现。
VOQ 缓冲结构
Per-(ingress, egress, priority) 独立队列,消除 Head-of-Line 阻塞。VOQ key = (ingress_port, egress_port, priority),每个 VOQ 是一个 FIFO 队列,存储等待调度的包。
全局缓冲池:所有 VOQ 共享 buffer_capacity_bytes(默认 16 MB)的全局缓冲。buffer_used 跟踪当前总占用,per_queue_bytes 跟踪每个 VOQ 的独立占用。
仿真中实际只使用 2 个优先级(2 和 3),因此 8 端口 Switch 的有效 VOQ 数量为 8 × 8 × 2 = 128。VOQ 规模随端口数和优先级数扩展,规模估算见附录 A。
优先级分类
优先级二值化:零字节包(payload_bytes == 0)映射 priority 3,数据包(payload_bytes > 0)映射 priority 2。
| 条件 | 优先级 | 用途 |
|---|---|---|
| payload_bytes == 0 | 3 (High) | tcredit、write_done 等控制消息 |
| payload_bytes > 0 | 2 (Medium) | 数据传输 |
@tbl-spec-switch-10 优先级分类
PAXI 行为分析文档 / VLAN PCP 映射描述多级优先级(High=3, Medium=2, Low=1),实际只使用两级,无 Low (1) 优先级流量。priority_count 配置(默认 4)未在 iSLIP 调度中使用。
设计依据:零字节控制消息(tcredit、write_done)延迟敏感,需要优先调度。所有数据包无论类型(allreduce、transfer 等)在 Switch 层面不做进一步区分。
与 PAXI 设计文档的差异:PAXI 行为分析文档推荐四级优先级映射(ACK/CNP=高,REQ=中高,RSP=中,TYPE2/3=低)。仿真简化为二值化,原因是仿真中 ACK/CNP 走 RSP VC(独立物理链路队列,不经过 Switch VOQ 排队),仅数据包和控制消息进入 Switch。
Dynamic Threshold 准入控制
包到达 Switch 后,根据 Dynamic Threshold 算法决定是否入队:
forward() 接口签名见附录 C。
实际公式(简化式):
$$\begin{equation} \text{allowed} = \alpha \cdot (B_{\text{capacity}} - B_{\text{used}}) \label{eq:sw-dt-admission} \end{equation}$$入队条件:$B_{\text{queue}} + \text{pkt\_bytes} \leq \text{allowed}$
与标准 DT 公式的差异:标准 DT 算法(Choudhury-Hahne)写的是 $T_q = \alpha \cdot B_{\text{free}} / N_{\text{active}}$,其中 $N_{\text{active}}$ 是活跃队列数。本实现与前置 spec 均省略 $N_{\text{active}}$ 除数(用上式简化)——每个队列获得相同的准入配额,不随活跃队列数变化。
与设计文档 DT 公式的差异:设计文档的 DT 公式为 $\text{Max\_Allowed} = \text{Static\_Reserved} + \alpha \cdot B_{\text{free}}$,包含 per-VOQ 的保底缓冲 Static_Reserved(如 128 KB/VOQ)。本 spec 省略 Static_Reserved,原因是仿真中全局缓冲共享(16 MB)远大于单 VOQ 需求,保底缓冲对准入决策影响极小,省略后简化实现且不影响仿真精度。
alpha 值的影响(来自设计文档):
| alpha 值 | 行为 | 适用场景 |
|---|---|---|
| < 1 | 保守:限制单个 VOQ 占用 | 多流量均衡 |
| = 1 | 均衡:平均分配剩余缓冲 | 默认推荐 |
| = 2(仿真默认) | 激进:允许更多突发 | Incast 突发吸收 |
| 4~8 | 深吸收:最大化突发容忍 | AllReduce 同步突发 |
@tbl-spec-switch-11 DT alpha 值行为对照
Incast 缓冲需求估算(来自设计文档):
$$\begin{equation} B_{\text{incast}} = (N - 1) \times BW \times T_{\text{burst}} \label{eq:sw-incast-buffer} \end{equation}$$示例(8 端口 × 200GbE,突发 10μs):$B = 7 \times 200\text{Gbps} \times 10\text{μs} = 1.75\text{MB}$(单出口端口)。
iSLIP 调度
每个 SwitchTick 执行 ISLIP_ITERATIONS(默认 2)轮 Request-Grant-Accept:
指针更新规则:只在第一轮迭代更新指针。
- 第一轮 (iteration == 0):匹配成功后,grant_pointer 和 accept_pointer 都更新为 (matched + 1) % N。这是标准 iSLIP 的去同步化技术——随机化初始状态后,指针自然分散,避免多个 egress 同时 grant 给同一个 ingress
- 后续轮 (iteration > 0):匹配成功后,对应端口从候选集中移除,但指针不更新。这防止后续轮的匹配扰乱第一轮建立的去同步化效果
设计依据:标准 iSLIP 论文证明,只在第一轮更新指针时,N×N 交换机在 N 轮迭代内可收敛到 100% 吞吐。如果每轮都更新,收敛性无保证。
吞吐率 vs 迭代次数(来自设计文档):
| 迭代次数 | 吞吐率 | 适用场景 |
|---|---|---|
| 1 | ~63% | 延迟最低 |
| 2(默认) | ~99% | 推荐 |
| 4 | ~99.9% | 高吞吐优先 |
@tbl-spec-switch-12 iSLIP 吞吐率与迭代次数
优先级与 iSLIP 的关系:当前实现中,iSLIP 不区分优先级。所有 (ingress, egress, priority) 的 VOQ 被扁平化到同一匹配池中。优先级的唯一效果是通过不同的 VOQ key 使不同优先级的包进入不同的队列,但调度时它们被平等对待。
高优先级(priority=3,零字节控制消息)更容易被调度的原因是隐式的:它们体积小(不易被 DT 拒绝),在 VOQ 中排队时间更短。
每 tick 最大匹配数:min(port_count,非空 VOQ 涉及的不同 ingress/egress 对数)。每个 ingress 和 egress 在单次 tick 中最多匹配一次。
tick 出队与转发
每个 SwitchTick 触发 iSLIP 调度后,匹配的 VOQ 执行出队和转发:
tick() 接口签名见附录 C。
出口序列化与 Overlap
每个 egress port 维护 port_busy_until 时间戳。出队包的延迟由 contention 等待、转发延迟、序列化三部分组成:
其中 $T_{\text{fwd}}$ = FORWARDING_LATENCY_NS(默认 30ns)。
port_busy_until 更新:
$$\begin{equation} \text{port\_busy\_until} = \text{now} + T_{\text{contention}} + T_{\text{serial}} \label{eq:sw-port-busy-update} \end{equation}$$更新不包含 $T_{\text{fwd}}$。这意味着 forwarding_latency 与后续包的 contention 重叠——下一个包可以在当前包仍在"转发"但已完成序列化时开始序列化。
等效关系:$\text{port\_busy\_until} = \max(\text{old\_port\_busy\_until}, \text{now}) + T_{\text{serial}}$,正确建模了出口端口的 FIFO 序列化队列。
设计依据:在真实交换机中,转发延迟(查表、crossbar 传输)发生在入口侧和 crossbar 内部,不占用出口端口的序列化资源。出口端口的 busy 仅取决于序列化时间。
时间槽:
$$\begin{equation} T_{\text{time\_slot}} = \text{frame\_size\_bytes} / \text{port\_bandwidth\_bytes\_per\_ns} \label{eq:sw-time-slot} \end{equation}$$SwitchTick 的调度间隔 = time_slot_ns,是 iSLIP 调度的最小时间粒度。port_bandwidth_gb_per_s 单位为 GB/s(= bytes/ns),直接使用。默认值 400 GB/s:1406 / 400 ≈ 3.5 ns。
不同帧类型在不同链路速率下的序列化延迟参考表见附录 A。
ECN 标记
ECN 标记在出队时执行(tick() 中 VOQ 出队后),不在入队时。标记使用出队前的 buffer_used / buffer_capacity 作为利用率。这意味着标记决策看到的缓冲包含正在出队的包本身,给出略微偏保守(偏高)的拥塞信号。
RED 概率标记:
$$\begin{equation} P(\rho) = \begin{cases} 0 & \rho < k_{\min} \\ \frac{\rho - k_{\min}}{k_{\max} - k_{\min}} & k_{\min} \leq \rho \leq k_{\max} \\ 1 & \rho > k_{\max} \end{cases} \label{eq:sw-ecn-red-probability} \end{equation}$$使用轻量级 Xorshift64 PRNG 生成随机数判定:rng.next_f64() < p → ecn_marked = true。PRNG 使用固定种子 0x1234_5678_9ABC_DEF0,保证仿真完全可复现。默认参数:$k_{\min}$ = 0.5, $k_{\max}$ = 0.8。
[NEEDS CLARIFICATION: ECN 阈值取 kmin/kmax = 0.5/0.8,与 DCQCN 设计文档的 0.3/0.8 不一致,待裁定统一值]
与设计文档的差异:设计文档的 CongestionController 使用 $P_{\max}$ 因子(默认 0.2),公式为 $P = P_{\max} \cdot (\rho - k_{\min}) / (k_{\max} - k_{\min})$,在 $\rho = k_{\max}$ 时 $P = 0.2$。本 spec 省略 $P_{\max}$(等效 $P_{\max} = 1.0$),在 $k_{\min} \sim k_{\max}$ 区间标记更激进,$\rho = k_{\max}$ 时 100% 标记。设计决策理由:仿真场景以 AI 集合通信为主,更激进的 ECN 标记可更快触发 DCQCN 降速,避免缓冲溢出丢包。如需与设计文档对齐,可在 SwitchConfig 中加入 ecn_pmax 参数。
零字节包不标记:payload_bytes == 0 的控制消息不触发 ECN 标记,即使缓冲利用率高。这是通过优先级分类(priority=3)间接实现的——ECN 标记应用于所有出队包,但零字节包体积极小,对缓冲利用率几乎无贡献。
与设计文档参数差异:DCQCN 设计文档中 ECN 参数为 kmin=0.3, kmax=0.8;Switch 实现默认 kmin=0.5, kmax=0.8。两者面向不同层面(per-port vs global buffer)。统一值待裁定(见上文 §ECN 标记 默认参数处的 NEEDS CLARIFICATION 标记)。
ECN 标记是 DCQCN 拥塞控制的触发源。完整闭环:
SwitchTick 自驱动与事件集成
Switch 使用自驱动的 tick 调度机制,不是固定周期轮询:有包就调度,无包则停止。
这创建了一个自维持的调度循环:有包就调度,无包则停止,避免空闲时的无效 tick 开销。
Switch 通过三个事件与仿真主循环交互:
C2CLinkDone(arrived_at = switch) → 调用 forward():
C2CLinkDone { arrived_at_node: "sw0", ... }
→ 查 switch.port_of(来源节点) → ingress_port
→ 查路由 next_hop → 查 switch.port_of(下一跳) → egress_port
→ switch.forward(ingress, egress, wire_bytes, ctx, now)
→ 如果入队成功且无 pending tick → schedule SwitchTick
SwitchTick { switch_id } → 调用 tick():
SwitchTick { switch_id: "sw0" }
→ results = switch.tick(now)
→ 对每个 result:
→ 查路由 next_hop(src_chip, final_dst, switch_id)
→ c2c_network.transmit(switch, next_hop, result.data_bytes, result.finish_ns)
→ schedule C2CLinkDone at finish_ns + 链路延迟
→ 如果 switch.has_pending() → schedule 下一个 SwitchTick
反向路由(ACK/NAK/CNP):ACK 等控制包从 RX 沿反向路由传回 TX 时,也经过 Switch。零字节 ACK 包以 priority=3 入 VOQ,享受较短的排队延迟。但 ACK 走的是 C2CNetwork 的 RSP VC 队列(独立于 REQ),只有进入 Switch 内部时才经过 VOQ 调度。
诊断计数器
SwitchModel 维护诊断计数器,通过 dump_stats(switch_id) 导出,包括 packets_forwarded、drops、ecn_marked、total_bytes_forwarded、buffer_peak_bytes、buffer_capacity_bytes、port_count。计数器完整列表与导出 key 见附录 C。
未导出的运行时状态:buffer_used(当前占用)、per-VOQ 队列深度、iSLIP 指针位置。这些状态可通过 has_pending() 间接观察。
端口分配与构造
构造时传入邻居节点名列表,按顺序分配端口号 0, 1, 2, ...。port_of(neighbor) 查询邻居对应的端口号。neighbor_to_port 映射在构造时建立。
备选方案
DT 公式:带 N_active vs 不带
| 维度 | 无 N_active (选定) | 有 N_active |
|---|---|---|
| 简单性 | 高:无需跟踪活跃队列数 | 低:需要 per-tick 计算活跃 VOQ |
| 公平性 | 每队列配额独立,不受其他队列影响 | 队列越多每个配额越小 |
| incast 行为 | 更宽松,允许更多突发 | 更严格,可能过早丢包 |
| AllReduce 适配 | 好(同步突发需要更大缓冲容忍) | 差(同步到达被惩罚) |
@tbl-spec-switch-15 DT 公式带/不带 N_active 对比
选择理由:AI 集合通信以同步突发(AllReduce incast)为主,N_active 除数会在所有端口同时发送时大幅缩小每队列配额,导致不必要的丢包。省略 N_active 更符合实际硬件的设计取向。
iSLIP 迭代数:2 vs N
| 维度 | 2 轮 (选定) | N 轮 |
|---|---|---|
| 吞吐率 (8 port) | ~99% | ~100% |
| 计算开销 | 低 | 高(8 轮) |
| 仿真精度 | 足够 | 边际收益极小 |
@tbl-spec-switch-16 iSLIP 迭代数 2 vs N 对比
选择理由:8 端口下 2 轮已接近 100% 吞吐,额外轮次的收益不足以证明计算开销。
优先级调度:扁平化 vs 严格优先级
| 维度 | 扁平化 iSLIP (选定) | 严格优先级 + iSLIP |
|---|---|---|
| 实现 | 简单:所有 VOQ 同一匹配池 | 复杂:per-priority 的 grant/accept pointer |
| 高优先级保证 | 隐式(零字节包体积小,排队短) | 显式(高优先级绝对优先) |
| 饥饿风险 | 无 | 低优先级可能饥饿 |
| 适用性 | 仿真中控制包占比极小 | 多优先级流量混合场景 |
@tbl-spec-switch-17 优先级调度扁平化 vs 严格优先级对比
选择理由:仿真中进入 Switch 的控制包(tcredit/write_done)体积极小(0 字节 payload),在 VOQ 中排队时间自然短,不需要显式优先级调度。ACK/CNP 走 RSP VC 独立物理链路,不经过 Switch VOQ。
流水线建模精度:固定延迟 vs per-stage
| 维度 | 固定 forwarding_latency (选定) | 12 级 per-stage |
|---|---|---|
| 精度 | 零负载下精确(~30ns) | cycle-accurate |
| 拥塞建模 | VOQ + iSLIP 覆盖排队争用 | 每级争用独立建模 |
| 实现复杂度 | 低 | 高:12 个独立 stage 状态机 |
| 仿真性能 | 好 | 差:事件量 ×12 |
@tbl-spec-switch-18 流水线建模精度固定延迟 vs per-stage 对比
选择理由:Switch 延迟变化的主要来源是排队争用(0 ~ 数十 μs),而非流水线级间差异(~2ns/stage)。VOQ + iSLIP 已精确建模排队行为,per-stage 的边际收益极小。
非功能性需求
| 维度 | 本 spec 的考虑 |
|---|---|
| 性能 (Performance) | Switch 是多芯片拓扑延迟主要来源(零负载约 250ns,incast 数十 μs)。固定延迟 + VOQ/iSLIP 抽象使事件量不随流水线级数膨胀;SwitchTick 自驱动避免空闲时无效 tick |
| 可靠性 (Reliability) | DT 准入控制在缓冲耗尽时丢弃(drops 计数),ECN 标记触发 DCQCN 降速形成拥塞响应闭环。无 N_active 的 DT 在极端 incast 下 buffer_used 可能超 capacity 理论计算值,alpha=2 配合 16MB 缓冲缓解 |
| 可观测性 (Observability) | 通过 dump_stats 导出 7 个诊断计数器(转发/丢弃/ECN/字节/峰值/容量/端口数);运行时状态经 has_pending() 间接观察 |
| 兼容性 (Compatibility) | PAXI Standard 格式假设:仅 Standard 格式支持 ECN,AFH 格式下 ECN 失效。固定种子 PRNG 保证跨拓扑/负载仿真可复现 |
| 安全性 (Security) | 不适用:Switch 是仿真内部模型,不暴露外部接口,无鉴权/数据加密需求 |
局限与后续工作
局限
| 风险 / 局限 | 影响 | 缓解措施 |
|---|---|---|
| 无 N_active 的 DT 可能允许总缓冲超限 | 极端 incast 下 buffer_used 可能超过 capacity 的理论计算值 | alpha=2 配合 16MB 缓冲在实际场景中够用 |
| 优先级不参与 iSLIP | 高优先级包无调度保证 | 零字节包体积小,排队时间自然短 |
| forwarding_latency overlap | 总延迟可能偏小 | 匹配真实交换机行为(转发不占出口资源) |
| 全局 buffer 利用率做 ECN(非 per-port) | 局部拥塞可能检测不到 | 简化模型,足够区分拥塞/非拥塞场景 |
| ECN kmin/kmax 参数与 DCQCN 设计文档不一致 | 标记阈值不统一可能影响拥塞响应 | 需确认并统一参数 |
| 固定种子 PRNG | 不同拓扑/负载下 ECN 标记序列相同 | 确定性是仿真优点(可复现),不影响统计特性 |
@tbl-spec-switch-19 风险与缓解措施
后续工作
| 方向 | 优先级 | 前置条件 |
|---|---|---|
| PFC PAUSE 支持 | 高 | 需要 Switch→Chip 反向事件通路 |
| 优先级感知 iSLIP | 中 | 需要 per-priority 的 grant/accept pointer |
| Per-port ECN | 中 | 需要 per-egress-port 的缓冲跟踪 |
| DWRR 出口调度 | 低 | 需要 per-egress 的 deficit counter |
| 带 N_active 的 DT | 低 | 需要 per-tick 活跃队列计数 |
| AFH 格式支持 | 低 | 需要 per-link 的帧格式配置,ECN 禁用 |
| 多播 TYPE2 支持 | 低 | 需要 VC4 + 双重流控 |
@tbl-spec-switch-22 未来方向
验收标准
| 场景 | 指标 | 目标值 | 测试方法 |
|---|---|---|---|
| 2 port 无拥塞 | 转发延迟 | ~forwarding_latency + serialization | 单包通过 Switch,测量端到端延迟 |
| 8→1 incast | DT 准入 | 部分包被 DT 拒绝(buffer 耗尽) | 8 端口同时发往 1 端口,检查 drop 计数 |
| iSLIP 公平性 | per-ingress 吞吐 | 各 ingress 吞吐差异 < 10% | 均匀负载下比较各 ingress 的调度次数 |
| ECN 概率标记 | 标记率 | kmin 以下 = 0,kmin~kmax 线性,kmax 以上 = 1 | 固定利用率下统计标记率 |
| SwitchTick 停止 | 空闲检测 | VOQ 清空后无新 tick | 所有包处理完后检查无后续 SwitchTick 事件 |
| ECN → DCQCN 闭环 | 速率收敛 | incast 后速率下降,结束后恢复 | 检查 ecn_marked > 0 且 diag_rate_block > 0 |
@tbl-spec-switch-20 验收标准
单元测试场景:
| 测试 | 输入 | 预期输出 |
|---|---|---|
| DT 准入丢弃 | buffer=200B, alpha=1.0,两个 150B 包同 VOQ | 第一个接受,第二个丢弃 (150+150 > 1.0*(200-150)=50) |
| ECN below kmin | buffer=10000B, kmin=0.5,入 1000B (利用率 10%) | ecn_marked = false |
| ECN above kmax | buffer=1000B, kmax=0.5,入 900B (利用率 90%) | ecn_marked = true |
| iSLIP RR | 3 ingress 都发往 egress 0, 3 个 tick | 3 个 ingress 各被选中 1 次 |
@tbl-spec-switch-21 单元测试场景
附录
附录 A:业界调研
硬件 12 级流水线分级(500MHz 时钟,2ns/cycle):
| 阶段 | 周期数 | 延迟 | 说明 |
|---|---|---|---|
| PHY_RX | 2 | 4 ns | SerDes 解串 |
| PARSER | 1 | 2 ns | 帧解析 (Eth/IP/UDP/BTH) |
| INGRESS_MATCH | 2 | 4 ns | TCAM/Hash 查表 |
| TRAFFIC_MANAGER | 1 | 2 ns | QoS 分类 |
| VOQ_ENQUEUE | 1 | 2 ns | 缓冲分配 + DT 检查 |
| ARBITER (3 steps) | 4-8 | 8-16 ns | iSLIP 2-4 次迭代 |
| XBAR_TRAVERSE | 1 | 2 ns | Crossbar 传输 |
| EGRESS_PROCESS | 1 | 2 ns | ECN/PFC 处理 |
| OUTPUT_SCHEDULE | 1 | 2 ns | 输出调度 |
| PHY_TX | 变长 | 30+ ns | 序列化发送 |
| 总计 (零负载) | ~15 | ~30 ns + 序列化 | 不含排队延迟 |
@tbl-spec-switch-02 硬件 12 级流水线分级
PAXI 帧格式与 Switch 功能约束:
| 格式 | 有 IP 头 | ECN 支持 | 最大帧大小 | 封装效率 |
|---|---|---|---|---|
| Standard | 有 | 支持 | ~1406B | 95.6% |
| AFH_GEN1 | 无 | 不支持 | ~1370B | 98.1% |
| AFH_GEN2_16b | 无 | 不支持 | ~1370B | 98.1% |
| AFH_Lite | 无 | 不支持 | ~1360B | 98.8% |
@tbl-spec-switch-03 PAXI 帧格式与 Switch 功能约束
序列化延迟参考表(来自 PAXI 行为分析文档):
| 帧场景 | 帧大小 | 100GbE | 200GbE | 400GbE |
|---|---|---|---|---|
| TYPE1 REQ 最大帧 (Standard+VLAN) | ~1406B | 112.5 ns | 56.2 ns | 28.1 ns |
| TYPE1 REQ 最大帧 (AFH_Lite) | ~1360B | 108.8 ns | 54.4 ns | 27.2 ns |
| TYPE1 ACK (Standard+VLAN) | ~54B | 4.3 ns | 2.2 ns | 1.1 ns |
| TYPE1 ACK (AFH_GEN1) | ~26B | 2.1 ns | 1.0 ns | 0.5 ns |
@tbl-spec-switch-04 序列化延迟参考表
VOQ 规模估算(来自 PAXI 行为分析文档):
| 交换机规格 | 端口数 | 优先级数 | VOQ 总数 |
|---|---|---|---|
| 小型 ToR | 8 | 4 | 256 |
| 中型 ToR | 16 | 4 | 1024 |
| 大型 Spine | 32 | 8 | 8192 |
@tbl-spec-switch-09 VOQ 规模估算
附录 B:实现说明
实现完成后补充,记录 spec 与实际实现的偏差。
- priority_count 配置默认为 4,未在调度中使用;所有优先级在同一 iSLIP 匹配池中。
- ECN kmin/kmax 默认值在 Switch 配置中为 0.5/0.8,与 DCQCN 设计文档中的 0.3/0.8 不同。
- Xorshift64 PRNG 使用固定种子 0x1234_5678_9ABC_DEF0。
- VOQEntry 记录 enqueue_ns,当前未用于延迟统计。
- port_busy_until 使用 HashMap 存储,旧条目不清理。
附录 C:完整接口签名 / 数据结构
接口签名
pub fn forward(
&mut self,
ingress_port: u32,
egress_port: u32,
data_bytes: u64,
ctx: PacketContext,
now_ns: f64,
) -> bool // true=接受, false=丢弃
pub fn tick(&mut self, now_ns: f64) -> Vec<SwitchForwardResult>
SwitchConfig
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| forwarding_latency_ns | f64 | 30.0 | 固定转发延迟(抽象 12 级流水线中 Stage 1-10) |
| port_bandwidth_gb_per_s | f64 | 400.0 | 每端口带宽 (GB/s),用于序列化延迟计算 |
| port_count | u32 | 8 | 物理端口数 |
| priority_count | u32 | 4 | 优先级数(配置字段,实际调度不使用) |
| buffer_capacity_bytes | u64 | 16 MB | 全局共享缓冲池总容量 |
| alpha | f64 | 2.0 | Dynamic Threshold 系数 |
| ecn_kmin | f64 | 0.5 | ECN RED 下阈值(缓冲利用率) |
| ecn_kmax | f64 | 0.8 | ECN RED 上阈值 |
| islip_iterations | u32 | 2 | iSLIP 迭代轮数 |
| frame_size_bytes | u64 | 1406 | 典型帧大小(仅用于计算 time_slot_ns) |
@tbl-spec-switch-05 SwitchConfig 字段
frame_size_bytes 的来源:1406B = Standard 格式最大帧(12B MAC + 4B VLAN + 2B Eth_type + 20B IP + 8B UDP + 8B RH + 1344B payload + 4B ICRC + 4B FCS)。
VOQEntry
| 字段 | 类型 | 说明 |
|---|---|---|
| ingress_port | u32 | 入口端口号 |
| egress_port | u32 | 出口端口号 |
| priority | u32 | 优先级(2 或 3) |
| data_bytes | u64 | 帧大小(字节) |
| ctx | PacketContext | 包元数据(src_chip, final_dst, slot_idx, psn, payload_bytes, txn_id, qp_id, vc_id) |
| enqueue_ns | f64 | 入队时间戳 |
@tbl-spec-switch-06 VOQEntry 字段
SwitchModel 状态
| 字段 | 类型 | 说明 |
|---|---|---|
| neighbor_to_port | HashMap<String, u32> | 邻居节点名 → 物理端口号(构造时按顺序分配) |
| voq | HashMap<(u32, u32, u32), VecDeque<VOQEntry>> | VOQ 队列池,key = (ingress, egress, priority) |
| per_queue_bytes | HashMap<(u32, u32, u32), u64> | 每个 VOQ 的字节占用 |
| buffer_used | u64 | 全局缓冲当前总占用 |
| grant_pointers | Vec<u32> | per-egress RR 指针(iSLIP Grant 阶段) |
| accept_pointers | Vec<u32> | per-ingress RR 指针(iSLIP Accept 阶段) |
| port_busy_until | HashMap<u32, f64> | per-egress 端口忙截止时间 |
| time_slot_ns | f64 | iSLIP 调度间隔 = frame_size_bytes / port_bandwidth_gb_per_s |
| rng | Xorshift64 | ECN RED 概率标记用 PRNG(固定种子,确定性) |
@tbl-spec-switch-07 SwitchModel 状态字段
SwitchForwardResult
| 字段 | 类型 | 说明 |
|---|---|---|
| ingress_port | u32 | 入口端口 |
| egress_port | u32 | 出口端口 |
| priority | u32 | 优先级 |
| data_bytes | u64 | 帧大小 |
| ctx | PacketContext | 原始包元数据(透传) |
| finish_ns | f64 | 包离开 Switch 的绝对时间 |
| ecn_marked | bool | 是否被 ECN 标记 |
@tbl-spec-switch-08 SwitchForwardResult 字段
诊断计数器
| 计数器 | 导出 key | 说明 |
|---|---|---|
| packets_forwarded | switch.{id}.packets_forwarded | 成功转发的包数 |
| drops | switch.{id}.drops | DT 准入控制丢弃的包数 |
| ecn_marked | switch.{id}.ecn_marked | ECN 标记的包数 |
| total_bytes_forwarded | switch.{id}.total_bytes_forwarded | 累计转发字节数 |
| buffer_peak_bytes | switch.{id}.buffer_peak_bytes | buffer_used 历史峰值 |
| buffer_capacity_bytes | switch.{id}.buffer_capacity_bytes | 配置的缓冲容量 |
| port_count | switch.{id}.port_count | 端口数 |
@tbl-spec-switch-13 诊断计数器
参数汇总
| 参数 | 含义 | 默认值 | 来源 |
|---|---|---|---|
| FORWARDING_LATENCY_NS | 转发延迟(抽象 12 级流水线) | 30 | 500MHz × ~15 cycles |
| PORT_BANDWIDTH_GB_PER_S | 端口带宽 | 400 | 硬件规格 |
| PORT_COUNT | 端口数 | 8 | 拓扑配置 |
| BUFFER_CAPACITY_BYTES | 总缓冲 | 16 MB | 硬件规格 |
| ALPHA | DT 系数 | 2.0 | AllReduce 突发优化 |
| ECN_KMIN | ECN 下阈值 | 0.5 | RED 配置 |
| ECN_KMAX | ECN 上阈值 | 0.8 | RED 配置 |
| ISLIP_ITERATIONS | iSLIP 迭代轮数 | 2 | ~99% 吞吐 |
| FRAME_SIZE_BYTES | 典型帧大小 | 1406 | Standard 格式最大帧 |
@tbl-spec-switch-14 参数汇总