跳到主要内容

G5 RC Link 传输层设计规格

版本:1.6.1 状态:Accepted 创建日期:2026-04-21 最后更新:2026-06-04 作者:xiang.li 前置互联通信G5仿真建模设计规格

变更历史

版本日期变更说明
1.5.12026-06-02修正 §VC 仲裁 RR 推进规则:vc_rr_ptr 只在实际发帧后推进,空 VC / 阻塞不推进
1.5.02026-06-01按新模板规范重构:9 节中文 H2 重排,新增 §名词定义 §非功能性需求,完整接口签名/参数表下沉附录 C
1.6.12026-06-04ISSUE-033 实施修正:TX cap 落地为 RcLinkTx frame_send_delay=max(datapath,serdes)(tx_busy 串行使单 LG=line_rate_per_lg);PhyLink per-edge 序列化保留与 per-LG cap 共存(撤 PhyLink chip 出口会 crash single-switch 425→21),撤回 1.6.0 的"撤 chip 出口序列化"+ 判别准则。§打包延迟 stage3/eq:rc-frame-done 已精修对齐 max 语义(datapath/SerDes pipeline 重叠取慢者,PhyLink per-edge 序列化保留共存)
1.6.02026-06-04ISSUE-033:TX SerDes 限速归属由 per-edge PhyLink 修正回 per-LG MAC credit(新增对称 RX 的 §芯片级聚合发送 cap + Goal G8)
1.4.22026-05-29新增 §芯片级聚合接收 cap,新增 Goal G7
1.4.02026-05-13ITLV 默认策略改为 hash-based,round_robin 降级为调试 baseline
1.3.02026-05-12新增 §事件粒度,重写 §打包延迟为 frame-level 序列化
1.2.02026-04-28新增 §多 Link Group 并行模型,接口加 lg_id 维度,diag 按 LG 分行
1.1.02026-04-21补全流程图与 ECN RED 公式,扩展 Non-Goals 与单元测试场景
1.0.02026-04-21初版:RC Link TX/RX 完整设计 + DCQCN 拥塞控制 + 物理链路双队列模型

@tbl-spec-rclink-01 文档变更历史


概述

RC Link 是 PAXI 协议栈的传输层,负责芯片间数据的可靠传输、流量控制和拥塞管理。本 spec 定义 G5 仿真中 RC Link 的完整设计:TX 侧的 Slot 管理、PSN 序列号、VC 仲裁、CBFC credit 流控;RX 侧的 PSN 校验、ACK MERGE 汇聚、credit 返还、芯片级聚合接收 cap;物理链路的 REQ/RSP 双队列模型;以及 DCQCN 动态拥塞控制回路。

背景

总 spec 对 RC Link 的描述停留在模块职责和参数表层面,缺少以下关键设计决策:

  • DCQCN 标注为"预留"但已完整实现:固定速率窗口 (RateCtrl) 已被动态速率状态机替换,spec 仍描述旧机制
  • 物理链路双队列未描述:REQ 和 RSP VC 使用独立序列化队列,ACK 不等待数据包,这是带宽建模的关键假设
  • RX 侧 credit 返还策略未明确:NAK 和重复包是否返还 credit 直接影响流控正确性
  • 流内 PSN 顺序保证未描述:防止乱序 NAK 风暴的设计决策未记录
  • ACK MERGE 需求驱动机制未描述:轮询调度策略影响 ACK 延迟建模

RC Link 是通信仿真精度的核心模块。DCQCN 是拥塞场景下带宽收敛行为的唯一建模手段。这些设计细节必须从设计文档和代码提取到 spec,作为验证基准。

名词定义

名词定义与易混淆概念的区分
RC LinkReliable Connection Link (RC Link),PAXI 协议栈传输层,提供可靠传输 / 流控 / 拥塞控制不是物理链路本身(物理串行化由下游 c2c_network PhyLink 承担)
SlotTX 侧追踪一个在途包的资源单元,状态机 Empty/WaitGrant/WaitAckper-LG 独立,不是 CBFC credit
PSN (Packet Sequence Number)12-bit 环形序列号,per-(lg_id, dst, qp_id) 独立递增EPSN 是 RX 侧期望值;PSN 是 TX 侧分配值
EPSN (expected_psn)RX 侧为每个 (src_chip, lg_id, qp_id) 维护的下一个期望 PSN是 RX 校验基准,不是 TX 的 next_psn
QP IDPAXI RCLINK 硬件可见字段 {XPU_ID, BANK},由 cdma_id 合成不是软件层 thread_id
vc_bankqp_id 低 BANK_W=2 位,决定包落入哪个 VC bank是 qp_id 的子字段,不是独立 ID
VC (Virtual Channel)虚拟通道,TX 按 vc_bank 分类,加权 RR 仲裁REQ/RSP 是物理链路 VC;此处指 TX 仲裁 bank
LG (Link Group)一组 x4 SerDes 构成的独立 C2C 通道,SG2262 每芯片 8 个每 LG 一份 RC Link 实例;不是 VC
ITLVsegment 级 LG 选择机制,默认 hash-based不是 packet 级散布
framePAXI/RCLink 接口最小粒度,= 一个 AXI burst,≤ MPS (4096B)是上层事件粒度;packet 是 frame 内重传单元
packetframe 内 Go-Back-N 重传单元,≤ max_payload (1344B)正常路径上不暴露为独立事件
MPS (Maximum Payload Size)frame 字节数上限,默认 4096B(硬件出处 TXBUFFERSIZE)是 frame 上限;max_payload 是 packet 上限
CBFC creditTX 在途 buffer 占用流控单位,per-(lg_id, dst, vc_id),粒度 256B是 in-flight 流控;与 MAC credit(发包节奏)不同
MAC creditMAC2TX_CREDIT,按 SerDes 线速控制发包节奏不是 CBFC credit(buffer 占用)
DCQCN基于 ECN/CNP 的动态速率拥塞控制,per-(dst, qp_id)替换了固定速率窗口 RateCtrl
ECNSwitch 对数据包的概率拥塞标记(RED 函数)Forward path 信号;CNP 是反馈信号
CNP (Congestion Notification Packet)RX 检测 ECN 后聚合生成的 64B 反馈包经 RSP VC,触发 TX 乘性减
ACK MERGERX 需求驱动的累积 ACK 汇聚机制FACK 绕过此机制
FACK (Fast ACK)零字节控制包绕过 ACK MERGE 的立即确认零字节,不占 CBFC credit(既不消耗也无返还)
Go-Back-NTX 收 NAK 后从间隙点回退重传的协议packet 粒度回滚

目标与非目标

目标

  • G1:完整定义 TX 侧 Slot 管理、PSN 分配、VC 仲裁、CBFC 流控的设计细节
  • G2:完整定义 RX 侧 PSN 校验、ACK MERGE、credit 返还、CNP 生成的设计细节
  • G3:定义物理链路 REQ/RSP 双队列模型和 CreditReturn 免序列化设计
  • G4:定义 DCQCN 完整拥塞控制回路(ECN 标记 → CNP 反馈 → 速率调整 → 速率恢复)
  • G5:明确 QP ID 编码契约 — qp_id 为 PAXI 硬件可见字段 {XPU_ID, BANK},由 cdma_id 和 vc_bank 合成,不依赖软件层 thread_id
  • G6:定义多 Link Group 并行模型 — 单流可通过 N 个独立 RC Link 实例 (per-LG) 散布到多 LG,每实例维护独立的 PSN/CBFC credit/Slot 池/Retry counter;保证单 LG 内严格保序,跨 LG 独立无干扰
  • G7:定义 RX 端芯片级聚合接收 cap — 镜像 TX 芯片级聚合发送 cap,约束单芯片数据接收聚合带宽 ≤ num_link_groups × line_rate_per_lg,按 per-LG 并行接收串行化,控制包(payload=0)绕过
  • G8:定义 TX 端芯片级聚合发送 cap — per-LG MAC credit 按 SerDes 线速 line_rate_per_lg 串行化(RcLinkTx frame_send_delay = max(datapath, wire/line_rate_per_lg),tx_busy 串行使单 LG = line_rate_per_lg),chip 8 LG 并行 -> 聚合 ≤ num_link_groups × line_rate_per_lg = 400。SerDes 限速绑定 LG(数量 = num_link_groups,SG2262 为 8,不随拓扑 edge 数变化)。与 PhyLink per-edge 序列化共存:chip 出口吞吐 binding = per-LG cap(50/LG),PhyLink edge(400)在多 edge 下不 binding、single edge 下与 per-LG 共同 400,无 double-throughput(busbw ≤ 400)。与 G7 RX cap 对称。(实施修正:初版拟撤 PhyLink chip 出口序列化,验证证明会 crash single-switch,改为保留共存,见 ISSUE-033)

非目标

  • PFC 链路级流控(需要 switch → chip 的 PAUSE 帧反向信令,复杂度高,已明确延后)
  • 多播 (TYPE2) 流控(双重约束模型,当前仿真不涉及多播)
  • 报文格式选择(AFH_Lite / Standard / AFH_GEN1 / AFH_GEN2_16b 的开销差异,当前使用固定 header_overhead)
  • RNR (Receiver Not Ready) 重传机制(硬件有 rnr_retry_counter,仿真中接收端始终 Ready,无 RNR 场景)
  • P_key 分区隔离(安全/多租户机制,性能仿真不涉及)
  • TYPE3 原始以太网报文(软件管理的 MD 机制,不在通信仿真范围内)
  • LITE 模式组网(不做端到端重传保护,QPID 编码不同,当前仿真仅支持标准模式)
  • 中断系统(MSI/电平中断定义属于硬件寄存器规格,仿真不建模中断)

用例说明

一个包从 TX 发出到 RX 确认的完整旅程

假设 Chip 0 的 PAXICore 已完成 MPS 分段,生成了一个 1344B payload 的 SegmentInfo,提交给 RC Link TX:

  1. TX 分配 Slot:从 512 个 Slot 池中找到一个 Empty Slot,分配 PSN(per-(dst=1, qp_id=3) 递增),Slot 状态变为 WaitGrant,包入 VC Bank3(因为 qp_id & 3 == 3)的待发队列

  2. TX VC 仲裁:加权 RR 轮到 Bank3,检查 CBFC credit 充足(消耗 6 个 credit,因为 ceil((1344+50)/256) = 6),检查 DCQCN 速率允许(now >= last_send + min_interval),三项都通过

  3. TX 打包发送:Slot 状态变为 WaitAck,打包延迟 = ceil(1394/64) = 22 ns,生成 RcPackDone 事件

  4. 物理链路传输:包进入 REQ VC 队列,经历排队等待 + 序列化 + 传播延迟,到达对端(或 Switch)

  5. RX 收包校验:PSN == expected_psn,校验通过。返还 6 个 credit(延迟 1ns)。包入 ACK MERGE 队列,调度 AckMergePoll

  6. RX ECN 检查:如果包的 ecn_marked == true,检查 CNP 聚合窗口(距上次 CNP >= 2500ns),满足则生成 CnpReceived 事件

  7. ACK 反向传输:AckMergePoll 触发,生成累积 ACK(覆盖所有已收包)。ACK 进入 RSP VC 队列(独立于 REQ,不等数据包),沿反向路由传回 TX

  8. TX 处理 ACK:释放 Slot(WaitAck → Empty),通知 PAXICore on_packet_acked

端到端时序图

下图展示一个包从 PAXICore 提交到 RC Link TX、经物理链路传输、由 RX 确认的完整时序:


详细设计

作用域说明:§Slot 管理 / §PSN 管理 / §VC 仲裁 / §CBFC 流控 / §打包延迟 描述的规则作用于单个 LG 实例内部——多 LG 配置下每个 LG 独立持有自己的 Slot 池、PSN 计数、credit 账本、retry counter、VC 仲裁状态。LG 之间状态完全独立。多 LG 整体设计见 §多 Link Group 并行模型。完整接口签名、调用关系、参数默认值见附录 C。

Segment Dispatch 机制

Segment 从 PAXI Core 的 segment_queue 喂入 RC Link TX 的 vc_pendingevent-driven push,不是 polling。这是硬件 spec 的 push 语义要求,也是 event-driven 仿真器的业界共识。

硬件 spec 依据

RCLINK_AFH_SPEC v2.4 §5.10 (P36L11 / P37L5):

上游下发的 TYPE1 数据报文会顺序进入一个队列中... 有上游下发新的数据报文写入队列时,该 slot 由 EMPTY 变为 WAIT_GRANT。

硬件 layer 2(队列接口)上,slot 状态由 "上游下发"事件 直接驱动,没有"polling 检查上游是否就绪"这一步。反压通过物理信号(FLOW_STOP / CBFC credit)实现,见 §CBFC 流控。

CDMA 端的 SerDes 物理串行化在仿真器层离散化为 segment + earliest_ready_ns,但 segment 的"物理就绪 → 喂入 slot"仍应按 push 语义触发,不应反复 polling 探测。

触发事件清单

物理事件仿真事件作用
CDMA 提交新 transfer(分段产生 segment)submit handler 内部计算 next_dispatch_at提交时刻 push 喂入 + schedule 下一次 dispatch
对端 ACK 到达释放 sloton_ack handler 内部计算 next_dispatch_atslot 释放 → capacity 增 → 可能可喂入更多
Segment 在 earliest_ready 时刻物理就绪SegmentDispatch event 触发之前 feed_rc_link 计算的 next_t 时刻
Datapath busy 释放(handle_rc_frame_done → on_tx_done)内部 try_arbitrate 接续发下一帧不需要单独 dispatch event

@tbl-segdispatch-triggers SegmentDispatch 触发事件清单

单一未决事件 + 防重 schedule

每个 chip 维护单一未决 SegmentDispatch timer:

  • feed_rc_link(now) 末尾返回 next_dispatch_at = min(segment_queue.front().earliest_ready_ns, ...)
  • 调用方(caller)拿到 next_dispatch_at 后,通过 reschedule_segment_dispatch helper:
    • 若 chip 有已 schedule 的 timer → kernel.cancel_timer(old_id)
    • next_dispatch_at 在未来 → kernel.schedule_timer(target, SegmentDispatch) 存新 id
  • SegmentDispatch handler 触发时:清掉 timer_id → feed_rc_link → 仲裁所有 LG → 重 schedule

此模式借鉴 ns-3 QbbNetDevice m_nextSend.IsExpired(),保证:

  1. wake 数 = 物理事件数:不再有 polling self-reschedule 膨胀
  2. latency 与仿真步长无关:每次 dispatch 时刻由物理参数(earliest_ready_ns)决定,与"任何噪音事件"是否插入无关
  3. 符合硬件 layer 2 push 语义:slot WAIT_GRANT 状态变化绑定真实 dispatch 时机

反例(已废弃)

旧实现使用 polling-driven RcLinkWake self-reschedule:

on_event(RcLinkWake) → feed_rc_link → schedule(RcLinkWake, next_wake)  // self-loop

此模式让 wake 数膨胀(tok=1024 N=64 达数千万次),且 segment 喂入时刻耦合 wake 频率,造成 latency 数值漂移。SegmentDispatch 替代后,wake 数严格 = 物理就绪事件数,符合 spec 与业界(ns-3 / htsim / OMNeT++ INET)实践。

详见 ISSUE-031 调研:docs/issues/ISSUE-031/{spec-true-semantics,des-dispatch-mechanisms,refactor-proposal}.md

TX 侧设计

Slot 管理

TX 维护一个大小为 TYPE1_OST(默认 512)的 Slot 池(per-LG 独立)。每个 Slot 有三个状态:

Empty → WaitGrant → WaitAck → Empty
↗ (NAK: Go-Back-N 回退)
  • Empty → WaitGrant:分配 Slot 时记录 (dst, qp_id, psn, payload, txn_id, vc_id),分配 PSN(per-(dst, qp_id) 递增),包入对应 VC 的待发队列
  • WaitGrant → WaitAck:VC 仲裁胜出后,消耗 CBFC credit,计算打包延迟,生成 RcPackDone 事件
  • WaitAck → Empty:收到覆盖该 PSN 的累积 ACK 后释放
  • WaitAck → WaitGrant:收到 NAK 时 Go-Back-N 回退

Slot 耗尽时,新包入 PAXICore 的 segment_queue 排队(见 PAXICore spec),ACK 释放 Slot 后由 PAXIBridge.feed_rc_link() 自动 drain。

PSN 管理

12-bit 环形序列号 (0-4095),per-(lg_id, dst, qp_id) 独立计数——每个 Link Group 实例维护自己的 PSN 序列空间,跨 LG 互不干扰。半区判定用于比较:

$$\begin{equation} \text{before}(a, b) = 0 < (b - a) \bmod 4096 < 2048 \label{eq:rc-psn-before} \end{equation}$$

ACK 为累积确认:ack_psn 表示该值之前的所有 PSN 已确认。

QP ID 编码:qp_id 是 PAXI RCLINK 层硬件可见字段 {XPU_ID, BANK}(PAXI RCLINK spec P37 L30 — LITE mode Source_qpid 字段定义同此格式,标准模式遵循同一布局)。仿真中按下式从 cdma_id 合成:

$$\begin{equation} \text{qp\_id} = (\text{cdma\_id} \ll \text{BANK\_W}) \mid (\text{cdma\_id} \bmod \text{NUM\_BANK}) \label{eq:rc-qp-id-encoding} \end{equation}$$

其中:

  • $\text{cdma\_id}$:当前 CDMA 实例的 chip 内 XPU 编号
  • $\text{BANK\_W} = 2$:bank 索引位宽(4 个 VC bank)
  • $\text{NUM\_BANK} = 2^{\text{BANK\_W}} = 4$:bank 数量
  • $\text{vc\_bank} = \text{cdma\_id} \bmod \text{NUM\_BANK}$:本 CDMA 落入的 VC bank

为什么 qp_id 必须基于硬件可见字段:软件层 thread_id 是 CDMA 内部命令调度概念,不出现在 PAXI/RCLINK 报文头。RX 侧通过报文头中的 qp_id 字段路由到对应 EPSN 上下文,必须与硬件一致。若 qp_id 用 thread_id:(a) 不同 CDMA 的 thread_id 可能撞号,导致 RX 端 EPSN 串扰;(b) 软件改变线程划分会破坏 PSN 空间分配,违反"软件改动不应影响硬件协议"。基于 {XPU_ID, BANK} 编码与 hash ITLV 输入对齐(见 §ITLV 分发机制),是硬件契约。

PSN 空间和 DCQCN 状态因此是 per-(lg_id, dst, qp_id)——粒度为 (target chip, link group, source XPU × bank),与硬件 RC Link 上下文一一对应。

为什么 PSN 必须 per-LG:N 个 LG 并行打包同一流的不同 segment 时,各 LG 的包几乎同时进入 c2c 物理链路并被序列化,到达 RX 顺序与全局 PSN 顺序不一致。若所有 LG 共享一个 PSN 序列,会触发 PSN gap → NAK 风暴。per-LG 独立 PSN 保证 RX 端按 (src_chip, lg_id, qp_id) 分别校验,单 LG 内顺序天然成立,跨 LG 无保序约束。这也是 IB dual-port HCA / NVLink multi-sub-link 的实际硬件做法。

VC 仲裁

5 个虚拟通道,按 qp_id 低位 vc_bank 字段分类(vc_bank = qp_id & (NUM_BANK-1),即 qp_id 的低 BANK_W=2 位,对齐 §PSN 管理 中的 qp_id 编码):

VC权重分类规则
Bank01vc_bank == 0
Bank11vc_bank == 1
Bank21vc_bank == 2
Bank31vc_bank == 3
MUL256多播(当前未使用)

@tbl-spec-rclink-02 TX 侧 VC bank 分类与仲裁权重(区别于 RCLINK 物理 8 VC)

加权 RR 机制vc_rr_ptr 指向当前轮到的 VC,vc_rr_counter 记录已发配额。指针只在实际发出报文后推进 —— 发一帧 counter++,达 weight 则指针前进到下一个 VC 并重置 counter;跨空 VC 切到新 VC 发帧时重置 counter。空 VC、credit 阻塞、rate 阻塞均跳过找下个 VC,但不推进指针、不动 counter。RR 状态绑定实际发送而非仲裁尝试次数,对齐硬件 RCLINK_AFH_SPEC §5.10「每次发出一个报文后」更新 bank mask 的语义;event-driven 仿真中若空扫也推进指针,RR 会耦合唤醒密度,使 latency 出现伪差。

仲裁决策流程(每个 VC 内):

  1. 取 VC 队列中的第一个 WaitGrant 包
  2. 检查 CBFC credit 是否充足
  3. 检查 DCQCN 速率是否允许
  4. 任一检查不通过 → 该包阻塞

流内 PSN 顺序保证:若某个 (dst, qp_id) 的 head-of-flow(队列中第一个 WaitGrant 包)被 credit 或 rate 阻塞,则同一 (dst, qp_id) 的所有后续包在本轮仲裁中全部跳过。这防止同一流内的乱序发送——乱序到达 RX 端会触发 PSN 间隙检测,产生不必要的 NAK 风暴。不同 (dst, qp_id) 的包仍可在同一 VC 内交错发送。

下图展示 TX 仲裁的完整决策流程,包括 LG 选择、credit 检查和 PSN 顺序保证:

与硬件仲裁的建模差异:硬件使用 bank mask 轮转机制(发包后按 qpid_msb 排除同 bank 的其他 Slot),G5 仿真简化为加权 RR。两者在公平性语义上等价——都确保各 bank 获得均等的发送机会——且都在「实际发出报文后」推进 RR 状态(硬件更新 bank mask / 仿真前进 vc_rr_ptr),不绑定仲裁尝试次数。微观单包调度顺序因 RR 实现不同而有差异;仿真关注宏观带宽分配和拥塞行为,单包顺序差异对 latency 的影响在 0.1-2% 量级。

CBFC 流控

Per-(lg_id, dst, vc_id) 粒度(每个 LG 实例独立维护与对端 RX 的 credit 账本),单位 credit_size(默认 256B)。

发送一个 packet 所需的 credit 数量由 payload 大小和包头开销决定:

$$\begin{equation} C = \lceil (\text{payload\_bytes} + \text{pkt\_ovhd}) / \text{credit\_size} \rceil \label{eq:rc-cbfc-credit-consume} \end{equation}$$

其中 pkt_ovhd 对应硬件的 PktOvhd 寄存器(有符号 10-bit),仿真中简化为 header_overhead(默认 50B)。

发送检查:剩余 credit >= 消耗量 + CREDIT_UF_LIMIT。CREDIT_UF_LIMIT(默认 1)确保至少保留一个最大包的 credit 余量,防止过度消耗导致反压失效。

初始 credit:仿真组装时统一设置,每个 LG 各 1024 个 credit 单位(默认)。N=8 配置下,每对芯片每 VC 共 8192 credit × 256B = 2 MB 缓冲深度。

事件粒度:frame-level 事件 + packet-level retry

PAXI SUE2.0 UserGuide §2.1.1 Flit Rules 规定 PAXI 把整个 AXI burst 打包成一个 frame("Paxi packages the entire write or read burst into a single frame and transmits it to the rclink"),frame 是 PAXI/RCLink 接口的最小粒度。MPS(Maximum Payload Size,默认 4096B)是 frame 字节数上限。

在 RC Link 内部,frame 进一步切成 packet(≤ max_payload,默认 1344B),但packet 仅是 Go-Back-N 重传粒度(PAXI UserGuide 中 TYPE1_PKT_LEN 的语义),不是 datapath 上的独立事件。MAC datapath 是字节级 pipeline,frame 内相邻 packet 在 datapath 上连续 line-rate 串行触发,无包间 stall

粒度大小角色事件
Frame≤ MPS (4096B)上层接口、序列化时间计算单位、CBFC credit 上报、ACK 通知 PAXICoreRcFrameDone(frame 整体进入 wire 完成)/ RcFrameAcked(远端 burst 响应回到)
Packet≤ max_payload (1344B)Go-Back-N 重传单位、PSN 单调递增追踪仅在 retry/NAK 路径触发包级事件,正常 path 上不暴露

@tbl-spec-rclink-event-granularity 事件粒度分层

契约约束

  • 上层(PAXICore)只感知 frame 级事件;packet 级状态对外不可见
  • frame 内多 packet 共享原子 slot 组:frame 整体占用 slot 组,frame 完成(含全部 packet ACK)后整组释放
  • frame 内 packets 在 datapath 上连续串行;datapath 占用时间 = frame 整体序列化时间
  • 重传时按 packet 粒度回滚(保留 PAXI UserGuide TYPE1 协议语义)

打包延迟与 MAC Credit

frame 发送在发送芯片内经历两段串接:NoC datapath 打包 + SerDes 序列化。RC Link TX 内部 datapath 占用时间按 frame 整体计算,仅覆盖 NoC 端进入 datapath FIFO 的打包时间;SerDes 物理串行化由 per-LG MAC credit 承担(chip 固定 8 个 LG/MAC,各按 line_rate_per_lg 释放 MAC2TX_CREDIT,聚合 chip 级上限,详见 §芯片级聚合发送 cap),不是 per-edge 物理链路(edge 数随拓扑变,LG 固定 8,见 §芯片级聚合发送 cap 的"为什么 per-LG 而非 per-edge"):

$$\begin{equation} T_{\text{frame\_send}} = \lceil \text{frame\_wire\_bytes} / \text{datapath\_bytes} \rceil \text{ ns} \label{eq:rc-frame-send-delay} \end{equation}$$

其中 frame_wire_bytes = frame_payload + frame_header_overhead(包括 packet 切分产生的逐包 header 累加,但 frame 整体作为一个事件触发完成时刻)。

两级延迟——芯片内 MAC(阶段 1 datapath 与阶段 2 SerDes 取慢者,per-LG)+ 物理链路(阶段 3 PhyLink per-edge 序列化 + 传播):

阶段模块公式物理含义粒度
1. NoC datapathRC Link TX$T_{\text{frame\_send}} = \lceil \text{wire}/\text{datapath} \rceil$MAC 从 NoC 拉数据进 datapath FIFO 的占用时间per-LG
2. SerDes 序列化per-LG MAC credit$T_{\text{tx\_serialize}}$(见 eq:rc-tx-serializeSerDes 字节级 line-rate 串行化,受 MAC2TX_CREDIT 节奏控制;与阶段 1 pipeline 重叠取慢者(见 eq:rc-frame-done);chip 8 LG 并行 → 聚合 cap = num_link_groups × line_rate_per_lgper-LG(chip 8 个)
3. 物理链路c2c_network PhyLink$T_{\text{phy}} = \text{wire}/\text{bandwidth} + \text{base\_latency}$per-edge 序列化 + 传播,对所有 edge 生效(保留共存,零改动);chip 出口吞吐 binding = 阶段 2 per-LG cap,PhyLink edge 非 throughput-bindingper-edge

@tbl-spec-rclink-frame-pipeline frame 端到端三段串接

frame 完成时刻(datapath 与 SerDes 取慢者,tx_busy 串行)——NoC datapath 与 per-LG SerDes 在 MAC 内 pipeline 重叠(非串接累加,避免 double-count),frame_send_delay 取二者慢者;tx_busy(bool) 在 frame_send_delay 期间串行化本 LG(serdes 50 < datapath 64 → serdes binding,单 LG 稳态吞吐 = line_rate_per_lg,chip 8 LG 并行聚合 = 400):

$$\begin{equation} T_{\text{RcFrameDone}} = \text{now} + \max(T_{\text{frame\_send}},\ T_{\text{tx\_serialize}}) \label{eq:rc-frame-done} \end{equation}$$

事件时序RcFrameDone$T_{\text{RcFrameDone}}$,见 eq:rc-frame-done)→ handle_rc_frame_done 触发 PhyLink → C2CLinkDone$+ T_{\text{phy}}$)→ RX 端 per-LG 接收串行化 + frame ACK 聚合。

ISSUE-033 修正:1.3.0(frame-level 重构)曾把 SerDes 序列化交给 per-edge PhyLink(T_phy = wire/line_rate + base_latency),与 §芯片级聚合发送 cap 的 per-LG MAC credit 表述矛盾。原始 spec RCLINK_AFH_SPEC §7.4.1 证明 SerDes 限速是 per-LG(per-MAC),故本版改回 per-LG(RcLinkTx frame_send_delay = max(datapath, wire/line_rate_per_lg),tx_busy 串行使单 LG = line_rate_per_lg)。PhyLink per-edge 序列化保留并共存:chip 出口吞吐 binding = per-LG cap,PhyLink edge 不 double-限吞吐(多 edge 不 binding / single edge 共同 400)。(1.6.1 实施修正:初版拟撤 PhyLink chip 出口序列化,验证证明 crash single-switch 425→21,改为共存,见 ISSUE-033)

硬件中 MAC 通过 credit 机制(MAC2TX_CREDIT_I,RCLINK_AFH_SPEC SS7.4.1)控制发包节奏:MAC 按 SerDes 线速字节级 pipeline 处理 frame 内容,frame 内相邻 packet 之间不产生额外 stall(MAC2TX_CREDIT 在 frame 序列化过程中按节拍连续释放)。frame 完成时 MAC 释放该 frame 占用的全部 credit。

SG2262 默认配置下,满 frame (4096B payload + 4 packet × 50B header ≈ 4296 wire bytes):

  • $T_{\text{frame\_send}}$(RC Link TX)= $\lceil 4296/64 \rceil$ = 68 ns
  • $T_{\text{phy}}$(PhyLink)= $4296/50 + 25$ = 110.9 ns
  • 端到端 = 68 + 110.9 = 178.9 ns

frame 内最后一个 packet 字节数不影响 $T_{\text{frame\_send}}$ 的连续性——小尾 packet 仅减少该 frame 的 wire_bytes 总量,不在 frame 内部产生额外 stall。frame 序列化期间该 LG 的 TX datapath 标记为忙,不处理新 frame;其它 LG 仍可并发处理新 frame。

硬件背景:SG2262 每芯片有 8 组 x4 SerDes Link,构成 8 个独立的 C2C Link Group (LG)。每 LG 由独立 MAC + PCS + FEC + SerDes 组成,与 PAXI Core 通过 NoC switch 解耦(CDMA → NoC → 任意 MAC,many-to-many)。同一笔通信可以散布到多个 LG。

建模结构
PAXI Core (1 个, 共享)
├─ AXI 事务管理 (W/R OST 总池)
├─ MPS 分段 (transaction → segments)
└─ ITLV LG 选择 (segment 级)

RC Link[0..N-1] ← N 个独立实例 (每 LG 一份)
每实例独立持有:
├─ Slot 池 (TYPE1_OST 个, per-LG 独立)
├─ PSN 序列 (per-(dst, qp_id), 在该 LG 内独立计数)
├─ CBFC credit (per-(dst, vc_id), 该 LG 与对端 RX 的账本)
├─ Retry counter (per-(dst, qp_id), 该 LG 的 Go-Back-N 状态)
├─ VC 仲裁状态 (vc_rr_ptr, vc_rr_counter)
└─ DCQCN per-QP rate state (per-(dst, qp_id))

TX datapath[0..N-1] ← N 个独立物理通道
├─ tx_busy 标志 (per-LG)
├─ 单 LG datapath_bytes 决定 pack_delay
└─ 单 LG line_rate 决定 DCQCN 速率上限

RX 侧对应 (per-(src_chip, lg_id, qp_id)):
├─ expected_psn (EPSN)
├─ ACK MERGE pending 队列
└─ pending CNP 状态

控制层共享 vs 数据层独立

状态归属
共享 (PAXI Core)W/R OST 总池,MPS 分段,segment 完成聚合1 个实例
独立 (RC Link, per-LG)PSN 序列,Slot 池,CBFC credit, retry counter, VC 仲裁状态,DCQCN per-QP rate, EPSN (RX)N 个实例

@tbl-spec-rclink-03 多 Link Group 并行模型:层,状态

ITLV 分发机制

分发粒度:segment 级(PAXI Core 切出 segment 时即决定走哪个 LG),不是 packet 级。

为什么 segment 级而不是 packet 级:同一 segment 的多个 packet 在同一 LG 内连续打包,PSN 连续递增。若 packet 级散布会破坏单 LG 内的 PSN 单调性(同一 segment 的 PSN 0,1,2 散到不同 LG,每 LG 看到 PSN 不连续)。segment 级分发自然保证单 LG 内 PSN 严格递增。

LG 选择策略(默认 = hash-based ITLV)

PAXI Core 在 submit() 切 segment 时,对每个 segment 计算 lg_id = hash(txn_id, frame_seq, qp_id) % num_link_groups

策略说明适用
hash_itlv (默认)lg_id = mix64(txn_id, frame_seq, qp_id) % num_lg,伪随机均匀分布生产路径,对齐硬件 spec
round_robin按 chip-level lg_rr_counter 轮转,每 segment 递增仅调试/baseline,存在周期共振问题
least_busy_lgtx_busy_until_ns 最小的 LG历史选项,try_arbitrate 反馈会导致负载不均(已弃用)
hash(qp_id)同 QP 固定到一个 LGper-flow affinity 调试

@tbl-spec-rclink-04 多 Link Group 并行模型:策略,说明

为什么默认 hash-based

  1. 硬件 spec 明确要求 hash:SG2262 C2C 方案规定"多个 c2c Link 之间做 ITLV (Hash)...同 src macid + 同 dst macid + 同 hash value 时路径相同且严格保序"。硬件支持 ITLV 粒度 1, 2, 4, 8, 16, 3, 6, 12 包,均使用 hash 索引,不是 round-robin counter。
  2. round-robin 存在周期共振:当 chip 内多个 unit 顺序 submit、每 unit segment 数恰好整除 num_link_groups 时,所有 unit 的 frame_seq=k 全部被分配到同一 LG。叠加 CDMA 注入门控的阶梯 earliest_ready_ns(每 segment 间隔 mps/bandwidth_ns),高 frame_seq LG 整体延后,critical path 拉长,导致仿真延迟 vs 消息大小非单调
  3. hash 的频谱平坦:伪随机分布让任何 segment 数 mod LG 数都不会锁相,frames 在 LG 上均匀分布,wire 利用率近 100%。
  4. 业界对齐:ECMP / CMS / RoCE flow steering 全用 hash(CRC32/Toeplitz/FNV/jump hash 等),不用 round-robin counter。

hash 函数实现要求

  • 输入:(txn_id: u64, frame_seq: u32, qp_id: u16) 三元组
  • qp_id 必须使用 §PSN 管理 定义的硬件可见编码({XPU_ID, BANK}),不可使用软件层 thread_id。理由:硬件 RC Link 报文头携带的就是该字段;hash 输入若与硬件不一致,仿真的 LG 分布会与硬件分布偏离,破坏带宽建模的可比性
  • 输出:u32u64,取 % num_link_groups 作为 lg_id
  • 性质:雪崩特性(输入 1 bit 改变 → 输出半数 bit 改变),无明显周期共振
  • 推荐实现:splitmix64 / FNV-1a 64 / xxhash3,禁止使用 (txn_id + frame_seq) % num_lg 这种线性组合(仍有共振)

保序保证:同一 (txn_id, frame_seq) 总是 hash 到同一 LG(hash 确定性),保证单 frame 内 packet 顺序;不同 frame 散到不同 LG 时由 RX 端 per-LG 独立 PSN 校验保证。

为什么 hash 优于 round-robin(设计原理)

核心反直觉:直觉上 round-robin "完美均匀分布",hash 有"碰撞",应该 RR 更优。实际上均匀的输入分配 + 有时间结构的 workload = 结构化负载——RR 把"输入序列的均匀性"传递成"负载时序的相位锁定",hash 反而打破这种锁定。

频谱特性对比

特性Round-RobinHash
总数分布完美均匀近似均匀(有碰撞)
频谱单频强峰(基频 = 1/N_LG)平坦(白噪声)
周期性确定周期 N_LG无周期
与周期性 workload 的相互作用共振(aliasing)独立

@tbl-spec-rclink-itlv-spectrum hash vs round-robin 频谱特性

这是采样定理的另一种表现:周期性采样 + 周期性信号 → aliasing。当上游 workload 具有时间结构(如多源顺序 submit、CDMA 注入门控阶梯 earliest_ready),RR 的固定周期会与 workload 周期共振。

Phase lock 数学模型

设 N_unit 个上游源顺序 submit,每源切出 K 个 frame;每 frame 的就绪时刻满足

$$\begin{equation} t_i = T_0 + i \cdot \Delta t, \quad i \in \{0, 1, ..., K-1\} \label{eq:itlv-ready-time} \end{equation}$$

其中 Δt 是 segment 注入间隔(= MPS / 注入带宽)。

RR 模式(K mod N_LG = 0,发生共振)

每源耗尽 N_LG 的整数倍轮次,每源结束时 counter 回到原点。因此 LG_k 仅接收所有源的 frame_seq=k:

$$\begin{equation} \text{LG}_k \text{ 收到的 frames}: \{(u, k) : u \in \text{所有源}\}, \quad k \text{ 固定} \label{eq:spec-g5-rclink-frame-receive} \end{equation}$$

这些 frame 的就绪时刻全部等于 $T_0 + k \cdot \Delta t$(同一时刻),LG_k 的"起跑线"被推后 $k \cdot \Delta t$

最坏情况 LG(k = N_LG − 1)的 critical path:

$$\begin{equation} T_{\text{crit}}^{\text{RR}} = T_0 + (N_{LG}-1) \cdot \Delta t + N_{\text{unit}} \cdot t_{\text{wire}} \label{eq:itlv-rr-crit} \end{equation}$$

Hash 模式

LG_k 收到的 frames 的 frame_seq 在 {0, ..., K−1} 上近似均匀分布。这些 frames 的就绪时刻分布在 $[T_0, T_0 + (K-1)\Delta t]$,期望 $\frac{K-1}{2}\Delta t$,标准差 $\sigma = \sqrt{\frac{(K-1)^2}{12}}\Delta t$

critical path:

$$\begin{equation} T_{\text{crit}}^{\text{hash}} \approx T_0 + \frac{K-1}{2} \cdot \Delta t + N_{\text{unit}} \cdot t_{\text{wire}} + O(\sigma) \label{eq:spec-g5-rclink-hash-critical-time} \end{equation}$$

差距(K = N_LG 时):

$$\begin{equation} T_{\text{crit}}^{\text{RR}} - T_{\text{crit}}^{\text{hash}} \approx \frac{N_{LG}-1}{2} \cdot \Delta t \label{eq:itlv-rr-hash-gap} \end{equation}$$

N_LG = 8、Δt = 64 ns 时约 224 ns 差距——这部分是 RR 引入的人工拖尾,不反映真实硬件行为。

物理类比:3 相电网平衡

场景3 相 RR 模式(电器同步轮转)3 相 hash 模式(电器随机开关)
各相平均功率完全均衡完全均衡
各相瞬时尖峰功率集中爆发(同时刻多电器开机)打散(随机分布)
系统所需变压器容量必须按尖峰设计(大)按平均设计即可(小)

@tbl-spec-rclink-itlv-power-grid 3 相电网类比 ITLV 策略选择

ITLV 中 LG 就是这 N_LG 相。RR 让所有源的 "第 k 帧" 在同一时刻进入 LG_k,造成 LG_k 内部尖峰累积。hash 把负载在时序上打散到所有相。

碰撞 vs Phase lock:统计性 vs 结构性 hot spot

担心 hash 碰撞会让某些 LG 过载是合理的,但定量地:

  • Hash 碰撞:是统计性的不均匀。LG 负载偏差 ∝ $\sqrt{N}$(大数定律),N 足够大时偏差被平均掉
  • RR Phase lock:是结构性的不均匀。LG 负载偏差 ∝ $N$(最坏 LG 负载比平均大 1 个 Δt 阶梯),且不随 N 增大而消失

结构性 hot spot 比统计性 hot spot 严重得多,尤其在 workload 具有规则时间结构时(CDMA 注入门控就是典型的规则时间结构)。

仿真器视角的特殊性:真实硬件靠 PHY clock skew、router queue jitter、SerDes 时钟漂移等"物理噪声"自然打散周期共振。仿真器没有这些物理噪声源,必须在算法层显式引入伪随机性(hash)才能让仿真行为接近真实硬件的稳态分布。

跨 LG 事务完成保证

同一 transaction 的多个 segment 散到不同 LG,每个 segment 有独立 txn_id。PAXI Core 收齐所有 segment 的 ack 后才视为 transaction 完成(生成 DataArrived 事件给上游 CDMA)。跨 LG 的 ack 无序到达不影响 transaction 语义——只是 OSTD 窗口允许的乱序完成。

芯片级聚合发送 cap

每个 LG 的发包速率受 MAC credit 约束(RCLINK_AFH_SPEC §7.4.1 MAC2TX_CREDIT_I):MAC 按 SerDes 线速 line_rate_per_lg 序列化完当前 frame 后才释放 credit,TX 无 credit 不可发下一 frame。每个 LG 维护独立发送串行化时间线(与 RX §芯片级聚合接收 cap 对称)。单 frame 发送串行化延迟:

$$\begin{equation} T_{\text{tx\_serialize}} = \frac{\text{frame\_wire\_bytes}}{\text{line\_rate\_per\_lg}} \label{eq:rc-tx-serialize} \end{equation}$$

每个 LG 的发送时间线按 busy 语义推进(镜像 RX eq:rc-rx-serialize):时刻 now 准备发送的 frame,发送完成时刻 = max(now, tx_lg_busy) + T_tx_serialize,并据此更新该 LG 的 tx_lg_busy。芯片级聚合发送带宽因此受限为 N 个 LG 串行化速率之和:

$$\begin{equation} BW_{\text{tx\_chip}} \le \text{num\_link\_groups} \times \text{line\_rate\_per\_lg} \label{eq:rc-tx-aggregate-cap} \end{equation}$$

SG2262:8 × 50 = 400 GB/s(与 SG2262 spec intra_bw = 400 GB/s 一致;与 RX 聚合上限相等,因收发共用同一组全双工 SerDes)。

为什么 per-LG 而非 per-edge:chip 物理出口是 8 个固定 SerDes 通道(LG),无论拓扑给它接几条 edge。SerDes 限速绑定 LG(MAC),与拓扑链路(edge)无关。若把发送序列化放在 per-edge 物理链路(如 1.3.0 frame-level 重构曾将 SerDes 交给 PhyLink),高 chip_radix 拓扑(cpb=8 板内 mesh / torus)下 chip 出向聚合 = edge 数 × per-edge 带宽,突破物理 8 × line_rate_per_lg(ISSUE-033 实测 chip0 TX 620-700 GB/s >> 400)。与 RX §芯片级聚合接收 cap 的 per-LG 设计完全对称。

控制包绕过:与 RX 对称,零字节控制包(FACK/ACK/NAK/CNP/CreditReturn)不占发送数据 cap。

关键性质(与 RX 对称):

  • N 条独立流:每流分配到一个 LG,N 流并行用满 N × line_rate_per_lg
  • 单流:通过 segment 级 ITLV 散布到多 LG,单流也能用满聚合带宽
  • N=1 退化为单 LG,所有 PSN/credit/Slot/SerDes busy 在单实例聚合

实现要求:在 RcLinkTx(per-LG 实例)try_arbitrateframe_send_delay = max(datapath_delay, wire/line_rate_per_lg)tx_busy(bool) 已串行化本 LG,故单 LG 吞吐 = line_rate_per_lg(serdes 50 < datapath 64,serdes binding),chip 8 个 RcLinkTx 并行 -> 聚合 400。tx_serdes_line_rate_per_lg 经 PAXIConfig 从芯片 YAML 注入(复用 paxi.tx.line_rate_per_lg,收发共用全双工 SerDes),0 时退化 datapath-only(fixture 绕过,对称 RX guard)。PhyLink per-edge 序列化保留并共存(§物理链路模型,零改动):chip 出口吞吐 binding = per-LG cap,PhyLink edge 不 double-限吞吐。(1.6.1 实施修正:初版拟撤 PhyLink chip 出口序列化以避免 double-serialize,验证证明撤 PhyLink crash single-switch 425→21,改为共存——per-LG binding 已使 busbw ≤ 400,PhyLink edge 非 throughput-binding,仅 latency 略增,见 ISSUE-033)。

RX 侧设计

PSN 校验与三种结果

RX 为每个 (src_chip, lg_id, qp_id) 维护 expected_psn (EPSN)——每个发送端 LG 在 RX 端有自己独立的保序窗口,跨 LG 不互相校验。收包时有三种结果:

条件结果行为
psn == EPSN接受EPSN++,入 ACK MERGE 队列,返还 credit,可选 CNP
psn > EPSN(环形半区判定)PSN 间隙生成 NAK,返还 credit
psn < EPSN(环形半区判定)重复包静默丢弃,返还 credit

@tbl-spec-rclink-07 PSN 校验与三种结果:条件,结果

关键设计决策:三条路径都返还 credit。无论 PSN 校验结果如何,包已经消耗了物理缓冲空间,必须返还 credit 以维持流控平衡。如果 NAK 或重复包不返还 credit,长时间的重传场景会导致 credit 泄漏,最终死锁。

下图展示 RX 收包的完整处理流程,包括 PSN 校验的三条路径(正序、NAK、重复):

FACK(Fast ACK)

零字节包(tcredit)绕过 ACK MERGE,立即生成 ACK。零字节包不占 CBFC credit(payload=0 时不占用 RX 数据缓冲,既不消耗也无返还)。设计目的:tcredit 是控制面握手消息,延迟敏感,不应等待 ACK 汇聚周期。

ACK MERGE 汇聚

需求驱动调度:不使用固定周期轮询,而是由收包事件触发。poll_scheduled 标志防止重复调度——只有在新包到达且无 pending poll 时才调度 AckMergePoll 事件(延迟 POLL_CYCLE_NS = 4ns)。

累积 ACK 生成:RX 跟踪 max_contiguous_psn(最后一个连续 PSN 的下一个值)。AckMergePoll 触发时,如果 pending_count > 0,生成一个累积 ACK,其 ack_psn = max_contiguous_psn,确认所有 PSN < ack_psn 的包。

MERGE_DEPTH(默认 64):单次 poll 最多合并的包数。超过此数时下次 poll 继续处理。

ECN 检测与 CNP 生成

收到 ecn_marked == true 的包时(PSN 校验通过后),RX 检查 CNP 聚合窗口:

  • Per-(src_chip, qp_id) 维护 last_cnp_ns
  • 若 now - last_cnp_ns >= CNP_INTERVAL_NS(默认 2500ns),生成 CnpReceived 事件,更新 last_cnp_ns
  • 否则忽略(窗口内抑制)
  • 零字节包(FACK/tcredit)即使 ECN 标记也不生成 CNP

[NEEDS CLARIFICATION: CNP 聚合窗口 spec 正文采用 2500ns,设计文档为 50000ns,两值差 20×,待确认权威默认值]

CNP 作为 64B 小包,沿反向路由(复用 ACK 路径)经 RSP VC 传回发端。

credit 返还

收包后延迟 CREDIT_RETURN_DELAY_NS(默认 1ns)生成 CreditReturn 事件。返还量使用与 TX 消耗相同的公式:

$$\begin{equation} C_{\text{return}} = \lceil (\text{payload\_bytes} + \text{pkt\_ovhd}) / \text{credit\_size} \rceil \label{eq:rc-credit-return} \end{equation}$$

CreditReturn 事件通过物理链路反向传输,但绕过序列化队列,仅经历传播延迟(见 §物理链路模型)。

芯片级聚合接收 cap

概念:RX 端镜像 TX 侧的芯片级聚合吞吐约束(见 §芯片级聚合发送 cap)。TX 侧每个 LG 的发包受 MAC credit 按 SerDes 线速 line_rate_per_lg 串行化释放;RX 侧对称——每个 LG 的收包同样按 line_rate_per_lg 串行化,N 个 LG 并行接收,芯片级聚合接收上限 = num_link_groups × line_rate_per_lg(SG2262:8 × 50 = 400 GB/s,与 TX 聚合上限相等,因为收发共用同一组全双工 SerDes)。

为什么需要:缺此约束时,高 radix 拓扑下单个芯片可同时从多个邻居接收,接收聚合带宽不受任何物理上限约束——与 TX 侧的芯片级 cap 不对称。流量集中(skewed)场景下,热点芯片的接收聚合会突破物理 SerDes 上限,使高 chip_radix 拓扑在仿真中获得不真实的接收带宽优势。

per-LG 并行接收串行化:收到的数据包(payload_bytes > 0)按 ITLV hash 落到对应 LG 的接收路径(与 TX 分发同一 hash 函数,与 src/dst 无关),每个 LG 维护独立的接收串行化时间线。单包接收串行化延迟:

$$\begin{equation} T_{\text{rx\_serialize}} = \frac{\text{payload\_bytes} + \text{pkt\_ovhd}}{\text{line\_rate\_per\_lg}} \label{eq:rc-rx-serialize} \end{equation}$$

每个 LG 的接收时间线按 busy 语义推进(与物理链路 eq:rc-link-delay 同构):到达时刻 now 的包,其有效接收完成时刻 = max(now, lg_busy) + T_rx_serialize,并据此更新该 LG 的 lg_busy。芯片级聚合接收带宽因此自然受限为 N 个 LG 串行化速率之和:

$$\begin{equation} BW_{\text{rx\_chip}} \le \text{num\_link\_groups} \times \text{line\_rate\_per\_lg} \label{eq:rc-rx-aggregate-cap} \end{equation}$$

控制包绕过payload_bytes == 0 的控制包(FACK、累积 ACK、NAK、CNP、CreditReturn)不计入芯片级数据接收 cap,也不经过 per-LG REQ 数据接收串行化。它们各自按既有物理链路模型处理:累积 ACK / NAK / CNP 走 RSP VC,按 §三层链路使用模型 经 RSP VC 序列化(与 REQ 数据队列独立,互不排队);CreditReturn 是 MAC 层信号,仅经历传播延迟(见 §CreditReturn 免序列化)。本节芯片级接收 cap 只约束 REQ 数据通道(payload > 0);控制包在独立的 RSP VC / MAC 信令通路处理,不占用 RX 数据接收带宽。

关键性质(镜像 §芯片级聚合发送 cap):

  • N 源 incast:多个 src 的流量按 hash 散布到 N 个 LG 接收路径,聚合接收上限 = N × line_rate;当 hash 把流量集中到单个 LG 时,该 LG 成为接收瓶颈(在收发共用同一 ITLV hash 前提下,真实反映 SerDes 端口的负载分布而非假设完美均衡;该前提破坏时的偏差见 §局限)
  • 单流:通过 segment 级 ITLV 散布到多 LG,单流也能用满聚合接收带宽
  • N=1 退化为单 LG,接收串行化在单实例聚合

与 DCQCN / CBFC 流控的关系:RX 聚合 cap 是独立于拥塞控制的物理接收约束,与现有机制作用维度正交:

机制约束对象触发条件
DCQCNTX 单流(per dst+qp)发包节奏交换机 buffer 拥塞标记 ECN
CBFC creditTX 在途(in-flight)buffer 占用credit 耗尽
RX 聚合 cap芯片级数据接收聚合带宽始终生效(物理上限)

@tbl-spec-rclink-rxcap-flowctrl RX 聚合 cap 与 DCQCN/CBFC 的维度区分

RX cap 推后包的接收完成时刻,进而推后该包的 CreditReturn 调度,使 credit 回流变慢,经 CBFC 对 TX 形成间接背压。这是物理因果(接收慢导致 credit 慢),不是与 DCQCN 的双重降速:二者约束不同的物理瓶颈(RX 入口聚合带宽 vs 路径中段交换机 buffer)。incast 下各源未必触发 ECN(各路径 buffer 未超阈值)却仍可聚合突破芯片接收上限——这正是 RX cap 要拦的、DCQCN 拦不到的维度。两者同时作用同一 TX 流时,叠加结果取更紧约束,符合真实硬件。

避免重复约束:业界 cycle-accurate 工具让聚合上限涌现于 per-port 串行化 + 共享仲裁,而非在其上叠加独立限速器。本模型的芯片级 cap 同样是 N 个 per-LG 串行化路径的自然求和,不是在 per-LG 串行化之外再设一个芯片级限速闸——聚合上限 num_link_groups × line_rate_per_lg 是 per-LG 串行化的数学结果,不重复约束。显式写出该上限是为对齐物理 NIC line-rate 语义并作为验收基准。业界对照见附录 A。

Go-Back-N 重传

NAK 触发

RX 检测到 PSN 间隙时生成 NAK。NAK 携带 ack_psn = EPSN(最后一个连续确认的 PSN 的下一个值),沿反向路由传回 TX。

TX 处理 NAK

  1. 检查重传计数是否超过 MAX_RETRY(默认 15),超过则标记错误
  2. 先做累积 ACK:释放 PSN < ack_psn 的所有 WaitAck Slot(这些包已被确认,不需要重传)
  3. 收集该 (dst, qp_id) 所有剩余的 WaitAck Slot
  4. 环形排序:按 psn.wrapping_sub(ack_psn) & PSN_MASK 排序,正确处理 12-bit PSN wrap-around
  5. 按 PSN 逆序 push_front 到 VC 队列头部,使最小 PSN 在队首(优先重传)
  6. 所有回退的 Slot 状态:WaitAck → WaitGrant
  7. 重传计数 +1

下图展示 Go-Back-N 重传的完整处理流程:

NAK 重传时序示例(PSN 空间 [5,6,7,8,9], NAK ack_psn=7):

Slot 状态 (NAK 前):
PSN 5: WaitAck ← PSN < 7, 已确认
PSN 6: WaitAck ← PSN < 7, 已确认
PSN 7: WaitAck ← 需重传
PSN 8: WaitAck ← 需重传
PSN 9: WaitAck ← 需重传

处理步骤:
1. 累积 ACK: 释放 PSN 5, 6 (Empty)
2. 收集: [PSN 7, 8, 9]
3. 环形排序: wrapping_sub(7,7)=0, wrapping_sub(8,7)=1, wrapping_sub(9,7)=2
4. 逆序 push_front: 先 9, 再 8, 再 7 → 队首 = PSN 7
5. 状态: PSN 7,8,9 全部 WaitAck → WaitGrant

超时重传

WaitAck 超过 RETRY_TIMEOUT_NS(默认 50000ns = 50us)未收到 ACK,视同 NAK 处理。超时重传使用 min_waitack_psn 作为基准 PSN(因为没有接收方反馈),对该 (dst, qp_id) 的所有 WaitAck Slot 执行 Go-Back-N。

物理链路模型

REQ/RSP 双队列

每条物理链路维护两个独立的 busy_until 时间戳

队列用途流量类型
REQ VC (busy_until_ns)数据包序列化SegmentInfo payload(从 TX 发往 RX)
RSP VC (busy_until_ns_rsp)ACK/NAK/CNP 序列化确认和控制包(从 RX 传回 TX)

@tbl-spec-rclink-08 REQ/RSP 双队列:队列,用途

这模拟硬件中 REQ 和 RSP VC 的独立数据通路(默认权重 8:8 WRR)。ACK 包永远不会排在数据包后面等待,确保确认路径的低延迟。

每个队列的延迟公式相同:

$$\begin{equation} T = \max(0, \text{busy\_until} - \text{now}) + \frac{\text{wire\_bytes}}{\text{bandwidth}} + \text{base\_latency\_ns} \label{eq:rc-link-delay} \end{equation}$$

ISSUE-033 — 与 per-LG 发送 cap 共存eq:rc-link-delaywire_bytes/bandwidth per-edge 序列化对所有 edge 生效(chip 出口 + switch 内部,PhyLink 零改动)。chip 出口吞吐由 §芯片级聚合发送 cap(per-LG MAC credit,binding)与本 per-edge 序列化共同约束:binding = per-LG(50/LG < edge 400),PhyLink edge 在多 edge 下不 binding、single edge 下与 per-LG 共同 400,不 double-限吞吐(busbw ≤ 400),仅 latency 略增。(1.6.1 实施修正:初版拟对 chip 出口撤 per-edge 序列化以避免 double-serialize,验证证明撤会 crash single-switch 425→21,改为保留共存,见 ISSUE-033)

CreditReturn 免序列化

CreditReturn 事件仅经历传播延迟(base_latency_ns),不经过任何序列化队列。设计依据:硬件中 credit 返还是 MAC 层信号(类似 PCIe/CXL/UCIe 的 credit flow),在物理层有独立的信令通路,不占用数据带宽。

三层链路使用模型

层级适用流量延迟模型
REQ VC数据包排队 + 序列化 + 传播
RSP VCACK/NAK/CNP排队 + 序列化 + 传播(独立队列)
MAC 控制CreditReturn仅传播延迟(无序列化)

@tbl-spec-rclink-09 三层链路使用模型:层级,适用流量

Relay 芯片处理

多跳路径中的中间芯片(relay)不经过 RC Link 处理。包到达 relay 芯片后,直接查路由表转发到下一跳物理链路,不做 PSN 校验、ACK MERGE 等处理。只有最终目标芯片才经过完整的 RX 处理流程。

报头开销估算

仿真使用固定 header_overhead(默认 50B),对应 Standard 报文格式。各格式的实际开销:

报文格式组成估算开销
StandardMAC(14B) + IP(20B) + UDP(8B) + RH(8B) + 可选ICRC(4B)~50-54B
AFH_GEN1压缩头 + 可选 TC 域~22-30B
AFH_GEN2_16b16-bit 地址压缩 + Key_words 标志位~16-20B
AFH_LiteTraffic Class 区分 TYPE1/TYPE2最小

@tbl-spec-rclink-10 报头开销估算:报文格式,组成

有效带宽受报头开销影响:

$$\begin{equation} BW_{\text{eff}} = BW_{\text{link}} \times \frac{\text{payload}}{\text{payload} + \text{header\_overhead} + \text{FEC\_overhead}} \label{eq:rc-effective-bandwidth} \end{equation}$$

默认配置下(payload=1344B, header_overhead=50B),有效带宽约为 payload/(payload+50) = 96.4% 的链路带宽。FEC 开销当前不建模(见 §局限与后续工作)。

序列保证规则

场景顺序保证说明
同 (dst, qp_id) TYPE1PSN 顺序发送 + Go-Back-N 保证按序交付
同 VC 同 DAVC 内 FIFO
不同 DA可能经过不同路径,延迟不同
不同 VCVC 间无排序约束
读写同地址需上层 fence/barrier 保证

@tbl-spec-rclink-11 序列保证规则:场景,顺序保证

DCQCN 拥塞控制

DCQCN 替换了原有的固定速率窗口 (RateCtrl),提供动态拥塞响应能力。

整体回路

Switch ECN RED 标记 → RX CNP 生成(聚合窗口) → TX 降速(乘性减)→ TX 速率恢复(快速恢复 + 加性增)

三条路径:

  • Forward Path:数据包经 Switch 时被 ECN 概率标记
  • Feedback Path:RX 检测 ECN 标记,生成 CNP 反馈给 TX
  • Recovery Path:TX 无 CNP 时通过 ByteCounter + TimeTimer 逐步恢复速率

下图展示 DCQCN 的完整事件回路,涵盖拥塞检测、反馈和速率恢复三条路径:

DCQCN 速率控制在以下三个状态间转换:

ECN RED 概率标记 (Switch 侧)

DCQCN 的 Forward Path 依赖 Switch 对经过的数据包进行 ECN 概率标记。标记概率基于出口缓冲的利用率 (utilization):

$$\begin{equation} P_{\text{ecn}}(\text{util}) = \begin{cases} 0 & \text{util} < K_{\min} \\ \dfrac{\text{util} - K_{\min}}{K_{\max} - K_{\min}} & K_{\min} \leq \text{util} < K_{\max} \\ 1.0 & \text{util} \geq K_{\max} \end{cases} \label{eq:rc-ecn-red-probability} \end{equation}$$

其中:

  • $K_{\min}$:ECN 标记开始的利用率阈值,默认 0.3(RoCEv2 典型值)
  • $K_{\max}$:ECN 必然标记的利用率阈值,默认 0.8
  • $\text{util}$:Switch 出口缓冲当前利用率 = 已用容量 / 总容量

伪随机数生成使用 Xorshift64 算法(确定性,可复现)。ECN 标记写入包的 ecn_marked 字段,RX 侧据此决定是否生成 CNP。

DCQCN 状态机 (per-QP)

Per-(dst, qp_id) 维护 DcqcnState:

NORMAL (rate = line_rate, 无 Timer)
↓ 收到 CNP
CONGESTED (rate < line_rate, ByteTimer + TimeTimer 并行)
├─ FastRecovery (stage <= 5): rate += (target - rate) / 2
└─ AdditiveIncrease (stage > 5): rate += line_rate / additive_increase_factor
↓ rate >= line_rate
RECOVERED → NORMAL (Timer 停止)
↑ 收到 CNP → 回到 CONGESTED

CNP 到达处理 (on_cnp)

  1. Alpha EMA 更新:$\alpha \leftarrow (1 - g) \cdot \alpha + g$
  2. 保存目标速率:$R_T \leftarrow R_C$
  3. 乘性减:$R_C \leftarrow R_C \cdot (1 - \alpha / 2)$
  4. 速率下限:$R_C \leftarrow \max(R_C, R_{\min})$
  5. 重置 byte_counter 和 recovery_stage_count
  6. 若 TimeTimer 未 arm,arm 之

速率恢复 (rate_increase)

两个触发源并行工作:

触发源条件行为
ByteCounter累积发送 >= byte_threshold (150KB)rate_increase() + 重置 counter
TimeTimer每 timer_interval_ns (55us)alpha 衰减:$\alpha \leftarrow \alpha \cdot (1-g)$,然后 rate_increase()

@tbl-spec-rclink-12 速率恢复 (rate_increase):触发源,条件

rate_increase() 两阶段恢复

$$\begin{equation} R_C \leftarrow \begin{cases} R_C + (R_T - R_C) / 2 & \text{stage} \leq \text{fast\_recovery\_stages} \\ R_C + R_{\text{line}} / \text{additive\_increase\_factor} & \text{stage} > \text{fast\_recovery\_stages} \end{cases} \label{eq:rc-dcqcn-rate-increase} \end{equation}$$ $$\begin{equation} R_C \leftarrow \min(R_C, R_{\text{line}}) \label{eq:rc-dcqcn-rate-cap} \end{equation}$$

recovery_stage_count++ 每次调用递增。

Timer 生命周期:timer_armed 标志防止重复调度。当 rate >= line_rate 时 Timer 停止(不再 reschedule)。

TX 速率限制 (pacing)

Rate-based pacing 而非 window-based:

$$\begin{equation} T_{\text{min\_interval}} = \frac{\text{header\_overhead} + \text{max\_payload}}{\text{current\_rate\_bytes\_per\_ns}} \label{eq:rc-dcqcn-pacing} \end{equation}$$

仲裁时检查 now >= last_send_ns + min_interval,不满足则 rate-block;该 dst,qp_id 的最早可发时刻 (last_send_ns + min_interval) 应通过 §Segment Dispatch 机制 的 next_t 路径精确 schedule,确保 pacing 阻塞解除时立即恢复仲裁,而非 polling 等候。

实施状态(v3.x):rate-block 精确 wake 当前未接入 feed_rc_linknext_t 路径——21 拓扑 alltoallv 评估中 DCQCN 全程 dormant(见 docs/issues/ISSUE-031/refactor-proposal.md 跨拓扑诊断,21/21 rate_block=0),incast / 高数据量场景需补;详见 ISSUE-031 Q-5。

单位约定:current_rate 内部单位为 bytes/ns(= GB/s)。C2C 链路带宽 bandwidth_gb_per_s 的单位即 GB/s(= bytes/ns),直接使用,无需除以 8。

诊断计数器

TX 维护诊断计数器用于瓶颈分析。完整计数器清单见附录 C。

备选方案

DCQCN vs 固定速率窗口

维度DCQCN (选定)固定速率窗口 (RateCtrl)
拥塞响应动态:根据 ECN 信号调整速率无:固定 86KB/1000ns 上限
精度能建模 incast 带宽下降和恢复无法建模拥塞行为
复杂度高:ECN + CNP + 状态机 + 双 Timer低:计数器 + 窗口重置
参数化8 个可调参数2 个参数

@tbl-spec-rclink-14 DCQCN vs 固定速率窗口:维度,DCQCN (选定)

选择理由:固定速率窗口无法建模网络拥塞的核心行为——有效带宽随负载变化。DCQCN 虽然复杂度高,但它是 RoCEv2 数据中心网络的标准拥塞控制算法,参数有 DCQCN 论文和工业实践支撑。

物理链路单队列 vs 双队列

维度REQ/RSP 双队列 (选定)单队列
ACK 延迟ACK 不受数据包排队影响ACK 排在数据包后面
硬件保真度匹配硬件 WRR 仲裁过度简化
实现复杂度两个 busy_until 跟踪一个

@tbl-spec-rclink-15 物理链路单队列 vs 双队列:维度,REQ/RSP 双队列 (选定)

选择理由:大量数据包在途时,单队列会导致 ACK 延迟膨胀,进而影响 credit 返还和 Slot 释放,产生级联效应。双队列消除了这一失真。

DCQCN 两阶段恢复 vs 硬件旧版三阶段恢复

维度两阶段 (选定)三阶段 (旧版硬件 DCQCN)
阶段FastRecovery + AdditiveIncreaseFastRecovery + AdditiveIncrease + HyperIncrease
降速公式$R_C \times (1 - \alpha/2)$$R_C \times (1 - \alpha / 2^{\text{alpha\_rate\_shift}+10})$
复杂度低:2 个分支高:3 个分支 + alpha_rate_shift 参数
参考来源DCQCN 论文原始算法硬件定制扩展

@tbl-spec-rclink-16 DCQCN 两阶段恢复 vs 硬件旧版三阶段恢复:维度,两阶段 (选定)

选择理由:G5 仿真采用 DCQCN 论文的标准算法(2 阶段),不引入硬件旧版的 Hyper Increase 扩展。两阶段恢复已足够建模拥塞后的速率收敛行为。alpha_rate_shift 参数使降速更平缓,但增加了参数调优复杂度,仿真中直接使用 $\alpha/2$ 更透明。

VC 仲裁:加权 RR vs 硬件 Bank Mask 轮转

维度加权 RR (选定)Bank Mask 轮转 (硬件)
调度语义每个 VC 服务 weight 次后轮转发包后按 qpid_msb 排除同 bank
宏观公平性等价等价
微观包顺序可能不同硬件精确
实现复杂度中(需维护 mask 集合)

@tbl-spec-rclink-17 VC 仲裁:加权 RR vs 硬件 Bank Mask 轮转:维度,加权 RR (选定)

选择理由:仿真关注宏观带宽分配和拥塞行为,不依赖精确的单包调度顺序。两种机制在统计意义上等价——都确保各 bank 获得均等的发送机会。加权 RR 更通用,参数化也更直观。

RX 聚合 cap:per-LG 并行 vs chip 级单一队列 vs 无 cap

维度per-LG 并行 (选定)chip 级单一队列无 RX cap
物理保真镜像 8 个 SerDes RX 端口,捕捉 hash 碰撞热点假设完美 LG 均衡,碰撞时高估接收接收聚合可无上限突破物理 cap
控制包payload=0 绕过(对齐 TX 侧 MAC 控制免序列化)易把控制包错计入数据带宽
聚合带宽正确性饱和态 = N × line_rate饱和态 = N × line_rate(等价)失真(可达物理上限数倍)
与 TX 对称性与 TX per-LG MAC credit 对称与 PhyLink per-edge 单 busy 形似但语义错配无对称
业界参照BookSim / Merlin / RDMA per-port 并行仅 ASTRA-sim analytical 单队列ASTRA-sim 纯 per-link(incast 虚高根因)

@tbl-spec-rclink-rxcap-alt RX 聚合 cap 建模方案对比

选择理由:per-LG 并行接收与 TX 侧 per-LG MAC credit 对称,且与业界主流(per-port 并行接收)一致。chip 级单一队列在饱和态聚合带宽上与 per-LG 等价,但假设完美 LG 均衡(hash 碰撞时高估单芯片接收能力),且若不显式区分会把控制包错计入数据带宽——为实现简单牺牲了 SerDes 端口分布的真实性。"无 cap" 是 incast/skewed 流量下接收带宽失真的直接来源,否决。

非功能性需求

维度本 spec 的考虑
性能 (Performance)TX 聚合发包上限 = num_link_groups × line_rate_per_lg(SG2262 = 400 GB/s);RX 聚合接收同上限;单 frame 端到端 ≈ 178.9 ns(datapath 68 ns + PhyLink 110.9 ns);有效带宽默认配置约 96.4%(受 header_overhead 影响)
可靠性 (Reliability)Go-Back-N 端到端重传(MAX_RETRY=15);超时重传(RETRY_TIMEOUT_NS=50us);三条 PSN 校验路径都返还 credit 防 credit 泄漏死锁;relay 芯片不做中间重传,由端到端 Go-Back-N 覆盖
兼容性 (Compatibility)N=1 退化为单 LG 模型,PSN/credit/Slot 状态在单实例聚合;qp_id 用硬件可见 {XPU_ID, BANK} 编码与硬件协议一致,软件改线程划分不影响 PSN 空间分配
可观测性 (Observability)按 LG 分行输出诊断计数器(diag_arb_tx_busy / diag_credit_block / diag_rate_block / diag_slot_full / diag_nak_* / diag_max_retry_hit),供瓶颈分析与验收检查
安全性 (Security)本 spec 模块在仿真器内部运行,不涉及鉴权 / 加密 / 多租户隔离(P_key 分区为非目标)

局限与后续工作

局限(本设计的代价)

风险 / 局限影响缓解措施
DCQCN 参数敏感性不当参数导致速率震荡或恢复过慢使用 DCQCN 论文推荐的默认值,提供诊断计数器验证
CNP 聚合窗口过大拥塞响应延迟增大默认 2500ns(远小于 RTT)
物理链路忽略 FEC 开销有效带宽略高于实际可通过 pkt_ovhd 参数修正
Relay 芯片不做 RC Link 处理多跳路径无中间节点可靠性保护端到端 Go-Back-N 已覆盖,无需中间重传
RX 聚合 cap 假设收发端 hash 分布一致若 RX 端 LG 分流与 TX 不同,per-LG 热点估计有偏差收发共用同一 ITLV hash 函数与同一组 SerDes,分布天然一致;偏差仅在 hash 实现不一致时出现,由 §ITLV 分发机制 的 hash 一致性要求覆盖

@tbl-spec-rclink-18 风险与缓解措施

.claude/rules/ 下的项目规则由 iforge-spec-review 在审核时整体核对。

后续工作(后续扩展方向)

方向优先级前置条件
PFC 链路级流控需要 Switch → Chip 反向 PAUSE 帧事件
多报文格式支持需要 per-link 的 header_overhead 配置
动态 credit_uf_limit 调节硬件仅 TYPE1 REQ 支持
Per-port ECN(替代 per-buffer)需要 Switch 出口端口级缓冲跟踪

@tbl-spec-rclink-21 未来方向

验收标准

场景指标目标值测试方法
无拥塞 2 芯片 P2P有效带宽>= 95% 线速比较仿真吞吐与 link bandwidth
4→1 incast 经 SwitchDCQCN 触发ECN 标记 + CNP 生成 + 速率下降检查诊断计数器 diag_rate_block > 0
incast 结束后速率恢复恢复到 line_rate检查 DcqcnState.current_rate == line_rate
CBFC credit 耗尽Slot 阻塞包等待 CreditReturn 后继续检查 diag_credit_block > 0 且最终完成
Go-Back-N NAK重传正确NAK 后包按 PSN 顺序重传检查 diag_nak_retransmit_total 和 PSN 连续性
ACK MERGEACK 减少单个 ACK 覆盖多包比较 ACK 数量 << 数据包数量
高 radix incast 接收 cap单芯片数据接收聚合带宽<= num_link_groups × line_rate_per_lg任意拓扑跑流量集中 workload,测峰值单芯片接收聚合带宽不超物理上限
高 radix chip 发送 cap (G8)单芯片数据发送聚合带宽<= num_link_groups × line_rate_per_lg多 edge chip(cpb=8 板内 mesh / torus)同时发多 dst,测峰值单芯片发送聚合带宽不超物理上限(ISSUE-033 复现:fat-tree-k16 ECMP S1 tok=1024 chip0 TX <= 400,修前 700)
控制包绕过数据接收 cap控制包接收延迟不随 REQ 数据接收队列增长(CreditReturn 仅传播延迟;ACK/NAK/CNP 经独立 RSP VC)高接收负载下控制包(payload=0)延迟不随数据接收队列长度变化

@tbl-spec-rclink-19 验收标准

单元测试场景

测试输入预期输出
PSN 半区判定before(4090, 5)true(跨 wrap)
PSN 半区判定before(5, 4090)false
CBFC credit 消耗payload=1344B, ovhd=50B, credit_size=256Bceil(1394/256) = 6
DCQCN on_cnpalpha=1.0, g=1/256, rate=50.0 bytes/nsalpha=0.9961+0.0039=1.0, rate=50*(1-0.5)=25.0 bytes/ns
ECN RED 概率util=0.55, kmin=0.3, kmax=0.8p = (0.55-0.3)/(0.8-0.3) = 0.5
ECN RED 边界util=0.2, kmin=0.3p = 0 (低于阈值)
ECN RED 边界util=0.9, kmax=0.8p = 1.0 (超过上限)
DCQCN rate_increase (FastRecovery)stage=1, R_C=25.0, R_T=50.0R_C = 25.0 + (50.0-25.0)/2 = 37.5
DCQCN rate_increase (AdditiveIncrease)stage=6, R_C=45.0, R_line=50.0, factor=200R_C = 45.0 + 50.0/200 = 45.25
Go-Back-N 环形排序PSN=[9,7,8], ack_psn=7排序后 [7,8,9],队首=7
RX 单 LG 接收串行化payload=1344B, ovhd=50B, line_rate=50B/ns,同一 LG 连收 2 包第 2 包接收完成 = 2 × (1394/50) ≈ 55.8 ns(串行,不并行)
RX 芯片级聚合 cap8 LG, line_rate=50B/ns, 8 源各发满芯片聚合接收 = 8 × 50 = 400 B/ns,不超
RX 控制包绕过payload=0 控制包在高接收负载下到达不进 per-LG REQ 接收串行化(延迟不随 REQ 数据队列增长)
TX 单 LG 发送串行化 (G8)frame_wire=1394B, line_rate=50B/ns,同一 LG 连发 2 frame第 2 frame 发送完成 = 2 × (1394/50) ≈ 55.8 ns(串行,不并行)
TX 芯片级聚合 cap (G8)8 LG, line_rate=50B/ns,多 edge chip 同时发多 dst芯片聚合发送 = 8 × 50 = 400 B/ns,不超(cpb=8 多 edge 不放大)
TX 控制包绕过 (G8)payload=0 控制包在高发送负载下不占发送数据 cap

@tbl-spec-rclink-20 Success Criteria:测试,输入


附录

附录 A:业界调研

Per-port 独立状态机

协议/IP多端口 RC 状态分布与本设计对应
InfiniBand dual-port HCA每 port 独立 RC(独立 PSN/QP retransmit context)
Mellanox ConnectX dual-port每 port 独立 reliable transport state
NVLink multi-sub-link (NVL3/4)每 sub-link 独立 retransmission context
CXL multi-stack Type-3每 stack 独立 ARQ

@tbl-spec-rclink-05 多 Link Group 并行模型:协议/IP,多端口 RC 状态分布

业界压倒性走 per-port/per-LG 独立物理层状态机模式(control plane 共享、data plane 多实例)。本模型与之对齐。

场景分发函数输入字段
ECMP(IP multipath)CRC32 / Toeplitz / FNV5-tuple(src/dst IP + protocol + src/dst port)
RSS(NIC RX 分流到多核)Toeplitz4/5-tuple
RoCE flow steeringhashQP id + flow key
NVLink lane balancingbyte-stripe(本质是 packet-level hash by addr)物理地址
PCIe multi-lanebyte-stripe物理地址
DASH disk stripinghash-based stripeblock id

@tbl-spec-rclink-itlv-industry 业界 multi-link 分发函数选择

业界几十年实践的共识:多源 + 时间结构化 workload 下必须用 hash,round-robin 仅在单源、无时间结构的场景下安全。

接收端聚合带宽建模对照

仿真器接收端聚合建模控制包处理
SST/Merlinper-port PortControl + 独立 xbar_bw,聚合上限涌现于 per-port 串行化 + crossbar 仲裁credit / CongestionEvent 独立 event,不占数据 buffer
BookSim 2.0per-subnet 并行 ejection,每路每 cycle 取 1 flitcredit 独立路径
ASTRA-sim(analytical)纯 per-link 单队列串行,无 node 级聚合 cap不建模控制包
真实 RDMA NIC(RoCEv2/IB)接收上限 = NIC 单 ingress link line-rate;incast collapse 即超此上限CNP / PFC 独立处理

@tbl-spec-rclink-rxcap-industry 业界接收端聚合带宽建模对照

本模型按 per-LG 并行接收串行化得到芯片级聚合 cap,与 BookSim(per-subnet 并行)、Merlin(per-port 并行)、真实 RDMA(per-port queue)的 per-port 并行接收结构一致;ASTRA-sim 的纯 per-link 单队列模型(无 node 级聚合约束)正是"高 radix incast 接收聚合虚高"的同款结构性缺陷,本设计否决该路线。

外部引用

附录 B:实现说明

记录 spec 与实际实现的偏差事实:

  • [2026-04-21] DCQCN 已完整实现(非"预留"),包含 ECN RED、CNP 生成/聚合、DcqcnState 状态机、ByteCounter + TimeTimer 恢复。
  • [2026-04-21] 物理链路 REQ/RSP 双队列已实现。CreditReturn 免序列化已实现。
  • [2026-04-21] CNP 聚合窗口默认值在代码中为 2500ns,DCQCN 设计文档中为 50000ns (50us)。两值不一致,待确认。
  • RcLinkTx::on_pack_done 在代码实现中命名为 on_tx_done

附录 C:完整接口签名 / 数据结构 / 参数

与单 LG 设计的接口改造点

§详细设计 各章节规则作用域为单 LG 实例内部。多 LG 改造在以下接口加 lg_id 维度:

  • RcLinkTx 实例化 N 份,每份持有独立 (slots, next_psn, vc_pending, credits, retry_counter, dcqcn_states, tx_busy)
  • submit_packet(lg_id, dst, payload, vc_id, txn_id, qp_id) — PAXI Core 在 segment 提交时确定 lg_id
  • try_arbitrate(lg_id, now) — 在指定 LG 实例内做 VC 仲裁
  • process_ack(lg_id, from_chip, qp_id, ack_psn) — ACK 路由到对应 LG
  • process_nak(lg_id, from_chip, qp_id, ack_psn) — NAK 触发 Go-Back-N 限定在该 LG
  • on_credit_return(lg_id, dst, vc_id, count) — Credit 返还到对应 LG
  • Event::RcPackDone { ..., lg_id } — 事件携带 lg_id
  • Event::C2CLinkDone { ..., lg_id } — RX 路由到对应 (src, lg_id, qp_id) EPSN
  • Event::CreditReturn { ..., lg_id } — Credit 反向通道也带 lg_id

RcLinkTx 公共接口

1.2.0 起 RcLinkTx 实例化为 N 份(每个 LG 一份,隶属于一个芯片的 PAXIBridge)。所有方法的状态作用域是单 LG 实例——对应 (chip_id, lg_id) 元组。lg_id 不出现在方法签名中,因为它已隐含在 &self。事件契约(Event)中需要显式携带 lg_id,让事件接收方路由到正确实例。

impl RcLinkTx {
/// 创建一个 LG 实例。chip_id 标识所属芯片,lg_id 标识在该芯片中的 LG 序号。
pub fn new(chip_id: u32, lg_id: u8, config: RcLinkTxConfig) -> Self;

/// 提交单个包到本 LG。分配 Slot + PSN(per-(dst, qp_id) 在本 LG 内独立计数),入 VC pending 队列。
/// 返回 true = 已分配 Slot;false = Slot 耗尽,调用方应排队。
pub fn submit_packet(
&mut self, dst: u32, payload_bytes: u32, vc_id: u32, txn_id: u64, qp_id: u16,
) -> bool;

/// 在本 LG 实例内做 VC 加权 RR 仲裁。成功时返回 (event_time, RcPackDone {..., lg_id: self.lg_id})。
pub fn try_arbitrate(&mut self, now_ns: f64) -> Option<(f64, Event)>;

/// 打包完成回调(事件中的 lg_id 已路由到本实例)。释放本 LG 的 TX datapath,尝试再次仲裁。
/// (代码实现命名为 on_tx_done)
pub fn on_pack_done(&mut self, now_ns: f64) -> Option<(f64, Event)>;

/// 累积 ACK:释放本 LG 内 PSN < ack_psn 的所有 WaitAck Slot。
/// 调用方负责按 (lg_id) 路由到对应实例。
pub fn process_ack(
&mut self, from_chip: u32, qp_id: u16, ack_psn: u16,
) -> Vec<SlotRelease>;

/// Go-Back-N:将本 LG 内 WaitAck Slot 回退到 WaitGrant 重传。
/// 返回 Err 当 retry_counter >= MAX_RETRY。
/// NAK 仅影响本 LG 的流,不波及其它 LG。
pub fn process_nak(
&mut self, from_chip: u32, qp_id: u16, ack_psn: u16,
) -> Result<(), &'static str>;

/// CNP 到达:对本 LG 内的 (from_chip, qp_id) 执行 DCQCN 降速。
pub fn on_cnp(&mut self, from_chip: u32, qp_id: u16) -> bool;

/// DCQCN TimeTimer 到期。
pub fn on_dcqcn_timer(&mut self, from_chip: u32, qp_id: u16) -> bool;

/// Credit 返还:增加本 LG 与对端 RX 在 (dst, vc_id) 上的 credit 账本。
pub fn on_credit_return(&mut self, dst: u32, vc_id: u32, count: u32);
}

RcLinkRx 公共接口

impl RcLinkRx {
/// 收包处理。PSN 校验 + credit 返还 + ECN/CNP + ACK MERGE。
/// 返回 RxResult { accepted, events }。
pub fn receive_packet(
&mut self,
src_chip: u32, qp_id: u16, psn: u16,
payload_bytes: u32, vc_id: u32, txn_id: u64,
now_ns: f64, ecn_marked: bool,
) -> RxResult;

/// ACK MERGE poll:生成累积 ACK 事件。
pub fn ack_merge_poll(
&mut self, src_chip: u32, qp_id: u16, now_ns: f64,
) -> Vec<(f64, Event)>;
}

调用关系

PAXIBridge.feed_rc_link()
├─> PAXICore.select_lg(segment) → lg_id ← ITLV: segment 级 LG 选择 (hash / RR / least_busy)
└─> rc_links[lg_id].submit_packet()
└─> rc_links[lg_id].try_arbitrate() ──> Event::RcPackDone { ..., lg_id }
└─> rc_links[lg_id].on_pack_done() ──> try_arbitrate() (链式)

Event::C2CLinkDone { ..., lg_id } ← 物理链路传输完成,携带 lg_id
└─> rc_links_rx[lg_id].receive_packet() ← RX 路由到对应 LG 实例
└─> 按 (src_chip, lg_id, qp_id) 校验 PSN → 生成 ACK/NAK/CNP

Event::AckArrived { ..., lg_id }
└─> rc_links[lg_id].process_ack() ← ACK 路由回发送侧对应 LG

Event::NakArrived { ..., lg_id }
└─> rc_links[lg_id].process_nak() ← NAK 触发的 Go-Back-N 限定在该 LG

Event::CreditReturn { ..., lg_id }
└─> rc_links[lg_id].on_credit_return() ← Credit 反向通道也带 lg_id

Event::C2CLinkDone (数据包到达)
└─> RcLinkRx.receive_packet()
├─> Event::CreditReturn (延迟 1ns)
├─> Event::AckMergePoll (延迟 4ns)
├─> Event::CnpReceived (条件: ECN + 窗口外)
└─> Event::AckArrived (FACK: 立即)

Event::AckMergePoll
└─> RcLinkRx.ack_merge_poll()
└─> Event::AckArrived (累积 ACK)

Event::AckArrived
└─> RcLinkTx.process_ack() ──> SlotRelease -> PAXIBridge.on_ack()

Event::NakArrived
└─> RcLinkTx.process_nak() ──> Slot 回退 + try_arbitrate()

Event::CnpReceived
└─> RcLinkTx.on_cnp() ──> DcqcnState.on_cnp()
└─> arm DcqcnTimeTimer (如需)

Event::DcqcnTimeTimer
└─> RcLinkTx.on_dcqcn_timer() ──> reschedule (如 rate < line_rate)

诊断计数器

计数器含义
diag_arb_calls单 LG 仲裁调用总次数
diag_arb_tx_busy单 LG 因自身 datapath 忙而跳过的次数(per-LG 实例视角;DIAG 输出按 LG 分行)
diag_credit_block因 CBFC credit 不足而阻塞的次数
diag_rate_block因 DCQCN 速率限制而阻塞的次数
diag_slot_full因 Slot 耗尽而阻塞的次数
diag_nak_processed处理的 NAK 数量
diag_max_retry_hit达到最大重传次数的流数量
diag_nak_retransmit_totalNAK 导致的重传包总数

@tbl-spec-rclink-13 诊断计数器:计数器,含义

参数含义默认值
num_link_groupsLG 实例数8(SG2262)
datapath_bytes单 LG MAC 处理位宽(决定 pack_delay)64B (512-bit)
line_rate_per_lg_bytes_per_ns单 LG SerDes 线速(决定 MAC credit 释放间隔和 DCQCN 速率上限)50 (= 400 GB/s ÷ 8 LG)

@tbl-spec-rclink-06 多 Link Group 并行模型 参数

为什么 datapath 和 line_rate 必须独立配置:硬件中 NoC 端处理位宽 (datapath) 通常宽于 SerDes 串行后的线速 (line_rate)。MAC datapath 64B/ns @1GHz = 512 Gbps,但 SerDes 经 PAM4 编码 + FEC 开销后单 LG 实际线速 50B/ns ≈ 400 Gbps。

TX 参数

参数含义默认值
TYPE1_OSTSlot 池大小512
HEADER_OVERHEAD每包头部开销50B
MAX_PAYLOAD最大包负载1344B
CREDIT_SIZECBFC 信用粒度256B
CREDIT_UF_LIMIT信用下限保留1
INITIAL_CREDIT初始 credit 数量1024
MAX_RETRYGo-Back-N 最大重传次数15
RETRY_TIMEOUT_NS重传超时50000
PACK_DATAPATH_WIDTH单 LG 打包 datapath 宽度64B (512-bit)
NUM_LINK_GROUPS物理 LG 实例数(TX 数据层并行度)8 (SG2262 默认)
LINE_RATE_PER_LG_BYTES_PER_NS单 LG SerDes 线速 (B/ns)50 (= 400 GB/s ÷ 8 LG)

@tbl-spec-rclink-22 TX 参数

RX 参数

参数含义默认值
MERGE_DEPTHACK MERGE 单次最大合并数64
POLL_CYCLE_NSACK MERGE 轮询延迟4.0
CREDIT_RETURN_DELAY_NScredit 返还延迟1.0
CNP_INTERVAL_NSCNP 聚合窗口2500

@tbl-spec-rclink-23 RX 参数

DCQCN 参数

参数含义默认值来源
initial_alpha初始 alpha 值1.0DCQCN 论文
galpha EMA 平滑因子1/256DCQCN 论文
byte_thresholdByteCounter 触发阈值150KBDCQCN 论文 (F)
timer_interval_nsTimeTimer 周期55000DCQCN 论文 (T)
min_rate_bytes_per_ns速率下限1.0 bytes/ns (= 1.0 GB/s = 8 Gbps)防止降到 0
fast_recovery_stages快速恢复阶段数5DCQCN 论文
additive_increase_factor加性增因子200DCQCN 论文

@tbl-spec-rclink-24 DCQCN 参数

ECN RED 参数 (Switch 侧)

参数含义默认值来源
ecn_kminECN 标记起始利用率0.3RoCEv2 典型值
ecn_kmaxECN 必然标记利用率0.8RoCEv2 典型值

@tbl-spec-rclink-25 ECN RED 参数 (Switch 侧) 参数