
在 RDMA 系统中一个非常典型的通信模式是RDMA Write ↓ RDMA Write ↓ RDMA Write-with-Immediate ↓ Remote CQE它的设计思想非常简单先把数据写到远端内存再通过 Write-with-Immediate 告诉远端“数据已经准备好了可以用了。”例如Sender Receiver │ │ │ RDMA Write: 4 MB Tensor │ ├────────────────────────────────────────────│ Remote Buffer │ │ │ Write-with-Immediate: READY │ ├────────────────────────────────────────────│ │ │ │ Generate CQE │ │ │ Application wakes up │ │ │ Read 4 MB Tensor这个机制看起来简单但对传统 RNIC 来说实际上提出了一个非常重要的要求RNIC 必须保证在远端应用收到 Write-with-Immediate 的 Completion Notification 之前前面的 RDMA Write 数据已经按照要求到达并对远端可见。否则就会出现严重的数据一致性问题。1. 为什么需要Write-with-Immediate普通 RDMA Write 的特点是Sender │ │ RDMA Write ▼ Remote Memory数据可以直接写进远端内存。但有一个问题远端 CPU 怎么知道这次 Write 已经完成普通 RDMA Write 通常不会主动给远端应用生成一个 Receive Completion。因此可能出现Remote Buffer 什么时候更新完成 CPU不知道一种方式是让 CPU 不停 Pollwhile(buffer-flag!READY){// spin}但这样效率不高。因此 RDMA 提供了RDMA Write with Immediate它同时完成两件事情Write-with-Immediate Sender RNIC │ ├─────────────── Data ──────────────→ Remote Memory │ └──────── Immediate Data ───────────→ Remote CQ也就是说写入远端 Memory在远端产生 CompletionCQE 中携带一个 32-bit Immediate Data。例如Immediate 0x00000001可以解释为Tensor #1 is ready2. 为什么常见的是Write ↓ Write ↓ Write-with-Immediate而不是每次都使用 Write-with-Immediate假设需要传输一个 4 MB Tensor。可以先WQE 1: RDMA WRITE Address Buffer 0 MB Length 1 MB WQE 2: RDMA WRITE Address Buffer 1 MB Length 1 MB WQE 3: RDMA WRITE Address Buffer 2 MB Length 1 MB WQE 4: RDMA WRITE Address Buffer 3 MB Length 1 MB最后WQE 5: RDMA WRITE WITH IMM Immediate READY于是接收端只需要收到一次通知CQE: Immediate READY就知道前面的 4 MB 数据全部完成因此 Write-with-Immediate 经常被当成一种Doorbell / Notification Mechanism即Data Data Data Data ↓ Doorbell3. 真正困难的问题不能让“通知”跑到“数据”前面假设 Sender 发WQE 1 RDMA Write(DATA) WQE 2 Write-with-Immediate(READY)从应用程序角度看DATA ↓ READY但底层实际上有很多异步组件Application │ ▼ Send Queue │ ▼ RNIC Pipeline │ ▼ Network │ ▼ Remote RNIC │ ▼ PCIe │ ▼ Host Memory于是存在一个危险场景。比如Packet carrying DATA ↓ Remote RNIC ↓ PCIe Write ↓ Host Memory与此同时Immediate packet ↓ Remote RNIC ↓ CQE如果 RNIC 不提供严格的排序保证就可能出现Time ───────────────────────────── Immediate arrives │ ▼ CQE generated │ ▼ CPU reads buffer DATA DMA still in progress ↓ Memory updated于是 CPU 会读到Old Data而不是New Data这显然是不允许的。所以传统 RNIC 必须实现Data-before-Notification ordering4. 第一层保证Send Queue WQE Ordering假设SQ WQE #100 RDMA Write WQE #101 RDMA Write WQE #102 Write-with-Immediate对于同一个可靠连接 QP例如RC QPRNIC 必须按照 WQE 的顺序处理。逻辑关系为WQE 100 ↓ WQE 101 ↓ WQE 102不能变成WQE 102 ↓ WQE 100 ↓ WQE 101因此 RNIC 内部需要维护QP Context │ ├── SQ Producer Index ├── SQ Consumer Index ├── Current WQE ├── PSN ├── Outstanding Requests └── Completion State这些状态通常就需要占用 RNIC 的片上 SRAM。5. 第二层保证Packet Sequence Number一个大型 RDMA Write 不会只变成一个网络包。例如1 MB RDMA Write可能被拆成Packet PSN 1000 Packet PSN 1001 Packet PSN 1002 ... Packet PSN 1200然后Write-with-Immediate可能继续使用PSN 1201形成PSN: 1000 1001 1002 ... 1200 1201 ← Write-with-Immediate因此 Receiver RNIC 可以知道如果 1201 到了 但是 1199 没到 那么不能直接认为前面的数据已经完成对于传统 RC TransportExpected PSN 1199 收到 1201说明存在 Gap需要进行NAK Retransmission Recovery因此 PSN 本质上提供了一套Transport-level ordering6. 第三层保证Remote RNIC 的 WQE/Packet 状态真正复杂的是 Remote RNIC。假设收到PSN 100 DATA PSN 101 DATA PSN 102 WRITE_WITH_IMMRemote RNIC 不能简单地收到 102 ↓ 马上生成 CQE而必须确保PSN 100 ↓ DMA complete / visibility requirement satisfied PSN 101 ↓ DMA complete / visibility requirement satisfied PSN 102 ↓ Write-with-Imm completion ↓ CQE因此 RX RNIC 内部需要维护很多状态RC QP Context Expected PSN Last ACKed PSN Current Message State DMA State Receive WQE State Immediate State CQ State所以Ordering并不是“网络天然就有”。而是 RNIC ASIC 里大量状态机共同实现出来的。7. 第四层PCIe Ordering这里开始进入真正的硬件问题。Remote RNIC 收到数据之后还要通过PCIe DMA把数据写进 Host DRAM。例如RNIC │ │ PCIe Memory Write ▼ Host DRAM所以完整链路其实是Network packet ↓ RNIC RX ↓ PCIe DMA ↓ Memory Controller ↓ DRAM与此同时RNIC 还可能Generate CQE ↓ PCIe Write ↓ Completion Queue所以存在两类 PCIe WriteA: Data DMA → Remote Buffer B: CQE DMA → Completion Queue关键要求是B 不能在语义上超越 A。否则CQE visible 但 Data not yet visible应用就会读到旧数据。因此 RNIC 必须利用PCIe ordering rulesDMA engine orderinginternal pipeline barrierscompletion scheduling确保DATA visibility ↓ CQE visibility8. 所以真正的 Write → Write-with-Imm 链条是简化来看Sender Application │ ▼ ┌─────────────────┐ │ Sender RNIC │ │ │ │ WQE 1 WRITE │ │ WQE 2 WRITE_IMM │ └────────┬────────┘ │ │ ordered packets ▼ ┌─────────────────┐ │ Network │ │ │ │ PSN 100 │ │ PSN 101 │ │ PSN 102 │ └────────┬────────┘ │ ▼ ┌─────────────────────────┐ │ Receiver RNIC │ │ │ │ PSN checking │ │ Reassembly │ │ DMA scheduling │ │ Ordering state │ └──────────┬──────────────┘ │ │ PCIe DMA ▼ Remote Memory │ │ data visible ▼ ┌─────────────────────────┐ │ Receiver RNIC │ │ │ │ Generate CQE │ │ Immediate READY │ └──────────┬──────────────┘ │ ▼ Completion Queue │ ▼ Remote CPU │ ▼ Read Data最核心的顺序是Data Transfer ↓ Data Visibility ↓ Immediate Notification ↓ Application Access9. 为什么这个机制特别消耗 RNIC SRAM这和现代 AI RNIC 论文讨论的hardware resource constraints直接相关。为了维护这种严格的可靠、有序传输传统 RNIC 对每个 QP 都可能保存QP Context ─────────────────── SQ state RQ state Expected PSN Send PSN ACK state Retry state Timeout state Outstanding WQEs DMA state Completion state RDMA Read state Atomic state Write-with-Imm state假设一个 QP Context 需要几百 Byte如果支持1,000,000 QPs理论状态规模就可能达到数百 MB显然不能全部放在最昂贵的高速 SRAM 中。因此传统 RNIC 经常需要复杂的On-chip SRAM Cache Host DRAM Context层级。10. 为什么 AI Cloud 给了 RNIC 新的优化机会传统 RNIC 设计目标是General-purpose RDMA因此必须考虑很多场景RDMA Write RDMA Write-with-Imm RDMA Read Send Receive Atomic Large number of QPs Reliable Transport Ordering Retry ...但是 AI 网络的行为高度规律。例如 AI Collective 可能大量使用RDMA Write Send/Recv Write-with-Immediate而某些复杂 Verbs 很少使用。因此论文作者会问能不能减少 Rare RDMA Verbs Complex connection state Some legacy semantics ↓ 释放硬件资源 ↓ 增加 Per-packet spraying Credit state Path state Reordering Congestion control这就是很多新型 AI RNIC 的设计哲学传统 RNIC 更多“通用性” ↓ AI RNIC 牺牲部分极少使用的通用能力 ↓ 换取更多 Multipath Congestion Control Credit Reordering11. Write-with-Immediate 和 Send/Receive 有什么区别这也是很容易混淆的一点。SENDSender Buffer │ │ SEND ▼ Receiver RNIC │ ▼ Receive BufferReceiver 必须提前Post Receive WQERDMA WriteSender │ │ WRITE ▼ Receiver MemorySender 直接指定Remote Address rkey远端 CPU 不直接参与。RDMA Write-with-Immediate可以理解成RDMA Write Remote Notification即Data ↓ Remote Memory 同时 Immediate ↓ Remote CQE因此它特别适合Data Plane Doorbell这种设计。12. 一个典型 AI / Storage 使用方式例如 Sender 要把 Tensor 写给 ReceiverTensor 64 MB可以WR 1 WRITE 16 MB WR 2 WRITE 16 MB WR 3 WRITE 16 MB WR 4 WRITE 16 MB WR 5 WRITE_WITH_IMM IMM Tensor_ID_123_READYReceiver 只需要 Poll CQpoll_cq();if(wc.opcodeRDMA_WRITE_WITH_IMMwc.imm_dataTENSOR_123_READY){process_tensor(buffer);}而无需不停检查 64 MB Tensor 是否到齐13. 一个非常重要的边界同一个 QP这种 ordering 最容易保证的是Same RC QP例如QP 7: WRITE A ↓ WRITE B ↓ WRITE_WITH_IMM存在明确的顺序关系。但如果QP1: WRITE DATA QP2: WRITE_WITH_IMM那么QP1 ─────────────→ QP2 ───────→两个 QP 在 RNIC 内部可能走不同Queue Scheduler Pipeline Path此时不能简单依赖程序提交顺序推导远端可见顺序因此需要 ordering guarantee 时应明确通信是否在同一个 QP/ordering domain 中。14.Fence也不要和这个问题混淆RDMA 中还有IBV_SEND_FENCE但它不是简单地说“所有 WRITE 后面都必须加 Fence。”Fence 主要用于某些前序操作例如RDMA Read Atomic存在返回数据/依赖关系时约束后续 Work Request 的执行。对于普通RDMA Write ↓ RDMA Write-with-Immediate在同一 RC QP 内基本的发送顺序和可靠传输语义本身就非常关键。所以不要把Write → Write-with-Imm ordering简单解释成靠 Fence 实现两者不是一回事。15. 为什么 Per-Packet Spraying 会让这件事情变复杂传统 RNIC 假设一个 QP ↓ 一条 ECMP Path所以P1 → Path A P2 → Path A P3 → Path A P4 → Path A网络中的 packet 顺序相对容易维护。但如果使用Per-packet spraying可能P1 → Path A ────────────────→ P2 → Path B ────────→ P3 → Path C ──────────→Receiver 实际收到P2 P3 P1这就直接打破了传统 RNIC 很重要的in-order packet arrival assumption而传统 Write → Write-with-Immediate 又要求DATA ↓ READY因此现代支持 packet spraying 的 RNIC 必须额外增加Out-of-order handling ↓ Packet tracking ↓ Selective retransmission ↓ Reordering ↓ Completion ordering才能最终保证即便 Packet Arrival 是 P3 P1 P2 P5 P4 应用看到的语义依然是 WRITE ↓ WRITE ↓ WRITE_WITH_IMM ↓ CQE这就是为什么Per-packet spraying 本身不难“既 spraying 又保持 RDMA 原有语义”才是真正难的地方。16. 一张图总结传统 RNIC 的工作Application │ │ │ WRITE │ WRITE │ WRITE_WITH_IMM ▼ ┌────────────────────────────┐ │ Sender RNIC │ │ │ │ SQ Ordering │ │ WQE State │ │ PSN Allocation │ │ Retry State │ └──────────────┬─────────────┘ │ ▼ Network │ ▼ ┌────────────────────────────┐ │ Receiver RNIC │ │ │ │ PSN Checking │ │ In-order Processing │ │ DMA Ordering │ │ Write Visibility │ │ CQE Ordering │ └──────────────┬─────────────┘ │ ┌──────┴──────┐ │ │ ▼ ▼ Remote DRAM CQE │ │ └──────┬──────┘ │ ▼ Application 保证 DATA visible ↓ READY notification总结传统 RNIC 中RDMA Write ↓ RDMA Write-with-Immediate本质上是一种非常常见的Data Doorbell通信模型。为了保证“收到 Doorbell” “前面的数据已经可以安全使用”RNIC 必须维护WQE Ordering PSN Ordering Reliable Delivery DMA Ordering Memory Visibility Completion Ordering因此传统 RNIC 需要大量QP state Packet state DMA state Retry state Completion state而这些状态最终会消耗宝贵的On-chip SRAM这也解释了为什么现代 AI RNIC 论文如此强调如何在保持传统 RDMA 语义的同时引入 per-packet spraying、credit-based congestion control 和 out-of-order transport而又不能让 RNIC SRAM 与状态复杂度爆炸。