对于熟悉传统数据中心网络的工程师来说,RDMA 最容易让人困惑的地方不是“协议格式”,而是它改变了主机网络栈的通信模型。

传统 TCP/IP 通信通常是:

1
2
3
4
5
6
7
8
应用 buffer
-> kernel socket buffer
-> TCP/IP stack
-> NIC
-> 网络
-> NIC
-> kernel socket buffer
-> 应用 buffer

而 RDMA 的目标是把数据路径变成:

1
2
3
4
5
应用注册内存
-> RNIC
-> 网络
-> RNIC
-> 远端应用注册内存

其中 CPU 不再负责搬运 payload,内核协议栈也不再处于数据面路径的中心。应用通过一系列队列、描述符和内存注册机制,把“我要读/写哪块内存”告诉 RNIC,由 RNIC 直接通过 DMA 访问主机 DDR,并在网络上完成可靠传输。

本文从传统网络工程师视角梳理 RDMA 通信架构,重点讨论:

  1. RDMA 通信抽象
  2. RDMA 通信的流程与原语
  3. RDMA 通信的数据通路
  4. RoCEv2 报文与拥塞控制
  5. RDMA 通信链路上各节点的带宽与瓶颈

1. RDMA 通信抽象

1.1 RDMA 的核心变化

RDMA 的核心不是“更快的 UDP”或“更快的 TCP”,而是通信抽象发生了变化。

在传统 socket 模型中,应用通常面对的是:

1
2
3
4
socket
send()
recv()
kernel protocol stack

而在 RDMA 模型中,应用面对的是:

1
2
3
4
5
Memory Region
Queue Pair
Work Queue Element
Completion Queue
RNIC

应用不再只是把字节流交给内核,而是提前注册内存,然后向 RNIC 提交任务描述符。RNIC 根据这些描述符直接访问本地或远端注册内存。


1.2 RNIC

RNIC,RDMA NIC,是支持 RDMA 语义的网卡。

它不仅负责普通网卡的收发包,还负责:

  • WQE 读取
  • QP 状态维护
  • DMA 读写主机内存
  • RDMA transport 处理
  • RoCEv2 封装与解封装
  • 可靠性处理
  • ACK / NAK / 重传
  • Packet Sequence Number 处理
  • Completion 生成
  • 拥塞控制与速率限制

从传统网络设备视角看,RNIC 相当于把一部分 transport 层和内存访问逻辑下沉到了网卡硬件/固件中。


1.3 Memory Region

RDMA 不能随便访问主机内存。应用需要先把一段内存注册给 RNIC,这段内存称为 Memory Region,简称 MR。

注册 MR 后,系统会生成访问 key:

Key 作用
lkey 本端 RNIC 访问本地 MR 时使用
rkey 远端 RNIC 访问本地 MR 时使用

例如,Host B 想允许 Host A 通过 RDMA Write 写入自己的一块内存,Host B 需要:

  1. 分配一块用户态 buffer;
  2. 注册为 MR;
  3. 获得 rkey 和 remote virtual address;
  4. 通过控制面把 rkey 和 remote address 告诉 Host A。

之后 Host A 才能构造 RDMA Write WQE,直接写 Host B 的这块内存。


1.4 QP:Queue Pair

QP,Queue Pair,是 RDMA 的核心通信端点。

一个 QP 通常包含:

  • Send Queue,简称 SQ;
  • Receive Queue,简称 RQ;
  • QP Context;
  • 关联的 Completion Queue;
  • QPN,Queue Pair Number;
  • PSN,Packet Sequence Number;
  • 远端 QPN;
  • transport 类型;
  • MTU、retry、timeout 等状态。

可以粗略把 QP 理解为“硬件化的通信上下文”。它有点像传统 socket,但又不完全等价。

传统 socket 主要抽象的是网络连接,而 QP 抽象的是:

1
通信端点 + 队列 + 传输状态 + 内存访问上下文

1.5 WQE:Work Queue Element

WQE,Work Queue Element,是应用提交给 RNIC 的任务描述符。

常见 WQE 类型包括:

WQE 类型 含义 是否需要远端提前 post receive
SEND 发送一条消息 需要
RECV 准备一个接收 buffer 本地操作
RDMA_WRITE 直接写远端内存 不需要
RDMA_WRITE_WITH_IMM 写远端内存,并携带 immediate data 通常需要远端 RECV WQE 接收通知
RDMA_READ 从远端内存读到本地内存 不需要
ATOMIC 远端原子操作 不需要

一个 RDMA Write WQE 里通常包含:

  • opcode;
  • local address;
  • length;
  • lkey;
  • remote address;
  • rkey;
  • signaled 标志;
  • SGE 列表。

SGE,Scatter-Gather Element,用来描述内存片段:

1
addr + length + lkey

RNIC 根据 WQE 和 SGE 知道该从哪里读、读多长、写到远端哪里,以及使用什么 key 做权限校验。


1.6 CQ 与 CQE

CQ,Completion Queue,用来承载完成事件。

当一个 WQE 完成后,RNIC 可以在 CQ 中写入一个 CQE,Completion Queue Entry。

应用通常通过 poll CQ 获取完成事件:

1
2
3
4
5
post WQE
doorbell RNIC
RNIC 执行任务
RNIC 写 CQE
应用 poll CQ

需要注意的是,不是每个 WQE 都必须生成 CQE。为了性能,RDMA 应用经常使用 unsignaled WQE,只让部分 WQE 产生完成事件,减少 PCIe 写和 CQ 处理开销。


1.7 RC、UD、RD 与 RoCEv2

RC:Reliable Connected

RC,Reliable Connected,是最常见的生产型 RDMA transport。

特点:

项目 RC
连接模型 一对一
可靠性 有 ACK、NAK、重传、PSN
支持操作 SEND/RECV、RDMA_WRITE、RDMA_READ、ATOMIC
典型场景 存储、AI、HPC、数据库、分布式 KV
类比 有点像硬件 offload 的可靠连接,但语义不是 TCP

RC 的代价是需要维护连接状态。大规模集群中,QP 数量、QP context cache、连接管理都会成为需要关注的问题。

UD:Unreliable Datagram

UD,Unreliable Datagram,是无连接、不可靠的数据报模式。

特点:

项目 UD
连接模型 无连接
可靠性 不保证
主要操作 SEND/RECV
RDMA Read/Write 通常不支持
类比 类似 UDP 风格的 RDMA datagram
典型场景 控制面、发现、部分低延迟消息场景

UD 不适合需要直接远端内存读写的主数据通路。

RD:Reliable Datagram

RD,Reliable Datagram,是 InfiniBand 架构中的一种可靠数据报传输服务。它的目标是提供可靠性,同时降低 RC 一对一连接状态的压力。

不过在主流 RoCEv2 数据中心实践中,最常见的仍然是 RC 和 UD。RD 不是大多数 RoCEv2 生产网络里的主流通信模型。

RoCEv2

RoCEv2,RDMA over Converged Ethernet v2,是把 RDMA transport 承载在 UDP/IP/Ethernet 之上的协议。

典型封装如下:

1
2
3
4
5
6
Ethernet
-> IP
-> UDP, dst port 4791
-> BTH / RDMA headers
-> Payload
-> ICRC

RoCEv2 的重要特点:

  • 可以三层转发;
  • 走 UDP/IP/Ethernet;
  • 可靠性不由 TCP 提供,而由 RDMA transport 提供;
  • 常见可靠模式是 RC;
  • 拥塞控制通常依赖 PFC、ECN、CNP、DCQCN 等机制;
  • 对丢包、拥塞、microburst、buffer 设计非常敏感。

2. RDMA 通信的流程与原语

2.1 建立通信前的准备流程

RDMA 通信不是直接 connect()send(),它需要先完成资源准备。

典型流程如下:

  1. 打开 RDMA device;
  2. 创建 Protection Domain;
  3. 分配并注册内存 MR;
  4. 创建 Completion Queue;
  5. 创建 Queue Pair;
  6. 修改 QP 状态;
  7. 交换连接信息;
  8. 进入 Ready to Send 状态;
  9. 开始 post WQE。

QP 通常经历如下状态变化:

1
2
3
4
RESET
-> INIT
-> RTR, Ready to Receive
-> RTS, Ready to Send

连接信息一般通过控制面交换,例如 TCP、RDMA CM、gRPC、服务注册系统等。

需要交换的信息包括:

  • QPN;
  • initial PSN;
  • GID / IP;
  • MTU;
  • remote address;
  • rkey;
  • transport type;
  • traffic class;
  • service level;
  • path MTU;
  • retry 参数。


2.2 Send/Recv 原语

Send/Recv 是双边语义。

发送端执行 SEND,接收端必须提前 post RECV。

流程如下:

1
2
3
4
5
6
7
8
Receiver post RECV WQE
Sender post SEND WQE
Sender RNIC DMA read 本地 buffer
网络传输
Receiver RNIC 匹配 RQ 上的 RECV WQE
Receiver RNIC DMA write 到接收 buffer
Receiver CQ 产生 CQE
Sender CQ 产生 CQE

如果接收端没有提前准备 RECV WQE,可能发生 RNR,Receiver Not Ready。

Send/Recv 更像传统消息通信,但数据搬运仍然由 RNIC 完成。


2.3 RDMA Write 原语

RDMA Write 是单边写操作。

发送端直接把本地数据写入远端已经注册并授权的内存区域。远端 CPU 不需要参与数据接收,远端应用也不需要提前 post receive。

流程如下:

1
2
3
4
5
6
7
8
Sender App post RDMA_WRITE WQE
Sender RNIC DMA read 本地 DDR
Sender RNIC 封装 RoCEv2 packet
网络转发
Receiver RNIC 校验 QPN / PSN / rkey / remote addr
Receiver RNIC DMA write 远端 DDR
Receiver RNIC 返回 ACK
Sender RNIC 生成 CQE

普通 RDMA Write 完成后,发送端知道数据已经写入远端内存,但远端应用未必立即知道。

如果需要通知远端,可以使用:

  • RDMA Write with Immediate;
  • Send/Recv;
  • 共享内存中的 flag;
  • ring buffer doorbell;
  • 应用层协议;
  • 远端轮询内存状态。

2.4 RDMA Read 原语

RDMA Read 是单边读操作。

发起端向远端发起 read request,远端 RNIC 从远端 DDR 读取数据并返回给发起端。

方向需要特别注意:

1
2
请求方向:Initiator -> Responder
数据方向:Responder DDR -> Initiator DDR

流程如下:

1
2
3
4
5
6
7
Initiator post RDMA_READ WQE
Initiator RNIC 发送 read request
Responder RNIC 校验 rkey 和 remote addr
Responder RNIC DMA read 远端 DDR
Responder RNIC 返回 read response
Initiator RNIC DMA write 本地 DDR
Initiator CQ 产生 CQE

RDMA Read 对远端内存带宽、远端 RNIC read pipeline、PCIe read latency 都比较敏感。


2.5 Atomic 原语

RDMA Atomic 用于远端原子操作,常见包括:

  • Compare-and-Swap;
  • Fetch-and-Add。

Atomic 通常用于分布式锁、计数器、队列元数据更新等场景。

但 Atomic 的性能和扩展性通常不如普通 RDMA Write/Read,因为它涉及远端序列化和一致性语义,容易成为热点瓶颈。


2.6 一次 RDMA Write 的完整流程

以 RC + RoCEv2 + RDMA Write 为例,完整流程可以表示为:

  1. Host B 注册目标内存,得到 remote address 和 rkey;
  2. Host B 通过控制面把 remote address 和 rkey 告诉 Host A;
  3. Host A 注册本地源内存,得到 lkey;
  4. Host A 创建 RDMA_WRITE WQE;
  5. Host A 将 WQE post 到 QP 的 SQ;
  6. Host A 通过 doorbell 通知 RNIC;
  7. RNIC fetch WQE;
  8. RNIC 查询 QP context;
  9. RNIC 查询 MR translation;
  10. RNIC 通过 PCIe DMA read 读取源 DDR;
  11. RNIC 切分 payload 并封装 RoCEv2 packet;
  12. packet 经过 Leaf/Spine 网络;
  13. 交换机根据 ECMP、QoS、ECN、PFC 策略处理;
  14. Host B RNIC 收到 packet;
  15. Host B RNIC 校验 BTH、PSN、ICRC、rkey、remote addr;
  16. Host B RNIC 通过 PCIe DMA write 写入目标 DDR;
  17. Host B RNIC 返回 ACK;
  18. Host A RNIC 收到 ACK;
  19. 如果 WQE 是 signaled,Host A RNIC 写 CQE;
  20. Host A 应用 poll CQ 得知完成。


3. RDMA 通信的数据通路

3.1 Zero-copy 的准确含义

RDMA 经常被称为 zero-copy,但这里的 zero-copy 需要精确定义。

RDMA 消除的是:

1
2
3
4
用户态 buffer -> 内核 socket buffer
内核 socket buffer -> 用户态 buffer
CPU 参与 payload copy
内核协议栈处理 payload 数据面

RDMA 没有消除的是:

1
2
3
4
RNIC 通过 PCIe 从源 DDR 读取数据
RNIC 通过 PCIe 向目标 DDR 写入数据
RNIC 内部 packet buffer / FIFO / pipeline 暂存
交换机内部 buffer 入队和出队

因此,更准确的说法是:

1
2
RDMA 是 host-side zero-copy 和 kernel bypass,
不是物理意义上的 no data movement。

3.2 发送端数据路径

发送端数据在 Host A DDR 中,RNIC 要把它发出去,必须通过 PCIe DMA read 把数据读入 RNIC TX pipeline。

路径如下:

1
2
3
4
5
Host A DDR registered buffer
-> PCIe DMA Read
-> RNIC TX FIFO / packetizer
-> Ethernet MAC
-> wire

这里一定存在一次:

1
Host DDR -> PCIe -> RNIC

但这不是 CPU copy,而是 RNIC 发起的 DMA read。

RNIC 不一定会把整个 message 完整缓存到片上内存中。高性能 RNIC 通常采用 streaming pipeline:

1
2
3
4
5
PCIe read completion stream
-> small FIFO
-> packetizer
-> TX scheduler
-> MAC

也就是说,它可能只缓存若干 cacheline、若干 packet 或若干 outstanding read completion,而不是缓存整个大对象。


3.3 接收端数据路径

接收端 RNIC 从 wire 收到 RoCEv2 packet 后,需要先进入 RX pipeline:

1
2
3
4
5
6
7
8
wire
-> Ethernet MAC
-> parser
-> packet buffer / reorder buffer
-> validation
-> DMA engine
-> PCIe Memory Write
-> Host B DDR registered buffer

对于 RDMA Write,接收端 RNIC 会校验:

  • Ethernet/IP/UDP;
  • BTH;
  • opcode;
  • QPN;
  • PSN;
  • ICRC;
  • rkey;
  • remote virtual address;
  • length;
  • access permission。

校验通过后,RNIC 通过 PCIe DMA write 把 payload 写入 Host B DDR。

因此,接收端也一定存在一次:

1
RNIC -> PCIe -> Host DDR

这也不是 CPU copy,而是 RNIC 发起的 DMA write。


3.4 一次 RDMA Write 的 DDR 到 DDR 数据路径

可以把完整数据路径概括为:

1
2
3
4
5
6
7
Host A DDR
-> PCIe DMA Read
-> Host A RNIC
-> Ethernet Fabric
-> Host B RNIC
-> PCIe DMA Write
-> Host B DDR


3.5 RDMA 能不能省掉这两次 PCIe 数据搬运

如果源数据在 Host A DDR,目标数据在 Host B DDR,而 RNIC 是 PCIe 外设,那么这两次数据运动无法省掉:

1
2
发送端:Host DDR -> RNIC
接收端:RNIC -> Host DDR

这是硬件拓扑决定的。

可以优化的是:

  • 减少 CPU copy;
  • 减少 kernel buffer copy;
  • 减少 descriptor fetch;
  • 减少 doorbell 次数;
  • 减少 CQE 数量;
  • 使用 inline data 优化小消息;
  • 使用 batching;
  • 使用 larger MTU;
  • 使用 GPUDirect RDMA 减少 GPU 到 CPU DDR 的 staging copy;
  • 使用 DPU、SmartNIC、CXL、SoC integrated NIC 改变拓扑。

但是 payload 从数据所在内存进入发送设备、再从接收设备写入目标内存,这个基本数据运动无法凭软件消除。


3.6 小消息 inline 优化

对于小消息,RNIC 可以支持 inline data。

普通发送路径是:

1
2
3
4
WQE descriptor
-> RNIC fetch WQE
-> RNIC DMA read payload
-> send

inline 路径则是:

1
2
payload 直接跟随 WQE / doorbell 写入 RNIC
-> RNIC 直接发送

这样可以减少一次 RNIC 对 host DDR 的 payload DMA read。

但 inline 适合小消息,不适合大块数据传输。因为它会增加 CPU 写 doorbell/WQE 的开销,并受 inline size 限制。


4. RoCEv2 报文与拥塞控制

4.1 RoCEv2 报文结构

RoCEv2 把 RDMA transport 放在 UDP/IP/Ethernet 上。

典型报文结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Ethernet Header
- dst MAC
- src MAC
- EtherType

IP Header
- src IP
- dst IP
- DSCP
- ECN
- Protocol = UDP

UDP Header
- src port
- dst port = 4791

RoCEv2 / InfiniBand Transport Header
- BTH, Base Transport Header
- opcode
- P_Key
- destination QPN
- PSN

Optional Extended Header
- RETH, RDMA Extended Transport Header
- remote virtual address
- rkey
- DMA length

Payload

ICRC

对于 RDMA Write,报文中通常会包含 RETH,因为接收端需要知道远端写入地址、rkey 和长度。


4.2 RoCEv2 为什么需要拥塞控制

传统 TCP 在端系统协议栈里有拥塞控制,例如 CUBIC、BBR、DCTCP 等。

RoCEv2 不走 TCP,而是走 UDP/IP。它的可靠性由 RDMA transport,例如 RC,负责。这样带来的问题是:

  • 交换机 buffer 满会丢包;
  • RDMA 对丢包和重传非常敏感;
  • incast 和 all-to-all 容易产生 microburst;
  • RNIC buffer 也有限;
  • PFC 虽然可以防丢,但可能引起拥塞扩散和 HOL blocking。

因此,RoCEv2 生产网络通常使用组合机制:

1
PFC + ECN + CNP + DCQCN

4.3 PFC:链路级流控

PFC,Priority Flow Control,是 IEEE 802.1Qbb 定义的基于优先级的链路级 pause 机制。

当交换机某个 priority queue 达到阈值时,可以向上游设备发送 pause frame,要求上游暂停该 priority 的发送。

流程如下:

1
2
3
4
5
Switch ingress queue buffer high watermark
-> send PFC pause to upstream port
-> upstream NIC / switch pauses one priority
-> queue drains
-> send resume / pause timer expires

PFC 的作用是防止 queue overflow,降低丢包概率。

但 PFC 的问题也很明显:

  • 粒度粗;
  • 按 priority pause,不按 flow pause;
  • 容易引起 head-of-line blocking;
  • 可能造成 congestion spreading;
  • 配置不当可能出现 PFC storm;
  • 大规模网络中 buffer 和阈值调优复杂。

所以 PFC 更像是最后一道“防丢保护”,而不是理想的端到端拥塞控制算法。


4.4 ECN 与 CNP

ECN 是 IP 层的拥塞标记机制。交换机在队列拥塞时,不直接丢包,而是在 IP header 的 ECN 字段上打 CE mark。

RoCEv2 中,典型拥塞通知流程如下:

1
2
3
4
5
6
7
8
Sender RNIC
-> data packet
-> congested switch queue
-> ECN CE mark
-> Receiver RNIC
-> generate CNP
-> Sender RNIC
-> reduce sending rate

CNP,Congestion Notification Packet,是接收端 RNIC 收到带 ECN CE mark 的 RoCEv2 packet 后发回源端的拥塞通知。

这里有三个角色:

角色 所在位置 职责
CP, Congestion Point 交换机队列 根据队列深度打 ECN
NP, Notification Point 接收端 RNIC 收到 ECN packet 后生成 CNP
RP, Reaction Point 发送端 RNIC 收到 CNP 后降速


4.5 DCQCN

DCQCN,Datacenter Quantized Congestion Notification,是 RoCEv2 网络中常见的拥塞控制算法。

DCQCN 的基本思想是:

  1. 交换机根据队列深度对 packet 打 ECN;
  2. 接收端 RNIC 收到 ECN-marked packet 后发送 CNP;
  3. 发送端 RNIC 收到 CNP 后降低发送速率;
  4. 如果一段时间没有继续收到 CNP,发送端逐步提高发送速率。

简化行为如下:

1
2
3
4
5
6
7
on CNP received:
reduce rate
increase congestion estimate alpha

periodically if no CNP:
increase rate
decrease congestion estimate alpha

DCQCN 通常包含:

  • multiplicative decrease;
  • additive increase;
  • hyper additive increase;
  • alpha 更新;
  • target rate;
  • current rate;
  • CNP rate limiting;
  • per-priority 或 per-flow rate control。

4.6 拥塞控制配置在哪些层面

RoCEv2 拥塞控制不是只配置在一个地方,而是分布在交换机、接收端 RNIC 和发送端 RNIC 上。

交换机侧

交换机主要配置:

  • RDMA traffic class;
  • DSCP/PCP 到 queue 的映射;
  • PFC enable priority;
  • ECN/WRED threshold;
  • buffer threshold;
  • scheduler;
  • ETS;
  • PFC watchdog;
  • lossless queue;
  • buffer headroom。

交换机一般不理解 QP 语义,只理解:

1
2
3
4
5
6
port
queue
priority
DSCP
ECN
buffer occupancy

接收端 RNIC

接收端 RNIC 作为 NP,负责:

  • 检测 ECN CE mark;
  • 根据 packet 关联的 QP/flow 生成 CNP;
  • 控制 CNP 发送间隔;
  • 设置 CNP 的 DSCP/PCP。

发送端 RNIC

发送端 RNIC 作为 RP,负责:

  • 接收 CNP;
  • 定位对应的拥塞上下文;
  • 对 flow/QP/priority 降速;
  • 执行速率恢复;
  • pacing;
  • rate limiting。

实际控制粒度取决于 RNIC 厂商和芯片实现,常见层级是:

1
2
3
port
-> traffic class / priority
-> QP / flow / congestion-control context

4.7 常见 RDMA 拥塞控制算法

DCQCN

RoCEv2 生产网络中最典型的拥塞控制算法之一。

特点:

  • 基于 ECN 和 CNP;
  • 交换机需要支持 ECN/WRED;
  • RNIC 负责响应和调速;
  • 适合 lossless 或 near-lossless fabric。

TIMELY

TIMELY 是基于 RTT/delay 的拥塞控制算法。

特点:

  • 不依赖 ECN;
  • 通过 RTT 变化判断拥塞;
  • 对时延测量精度敏感;
  • 对硬件时间戳和 RTT 采样要求较高。

HPCC

HPCC,High Precision Congestion Control,基于 INT,In-band Network Telemetry。

特点:

  • 使用更精确的网络遥测信息;
  • 能根据链路利用率和队列信息做细粒度控制;
  • 依赖交换机 INT 能力和端侧支持;
  • 部署门槛高于 DCQCN。

IRN

IRN 更偏向改进 RDMA 在有损网络中的丢包恢复能力,而不是单纯的速率控制算法。

它通常关注:

  • selective retransmission;
  • limited out-of-order handling;
  • 减少对完全 lossless fabric 的依赖。

5. RDMA 通信链路上各节点的带宽与瓶颈

RDMA 性能问题通常不是单点问题,而是整条链路上的任意一个节点都可能成为瓶颈。

可以把一条 RDMA Write 链路拆成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Source DDR
-> CPU memory controller / NUMA
-> PCIe Root Complex
-> PCIe link
-> RNIC DMA engine
-> RNIC packet pipeline
-> NIC port
-> ToR / Leaf
-> Spine
-> Leaf / ToR
-> NIC port
-> RNIC RX pipeline
-> PCIe link
-> PCIe Root Complex
-> Target DDR


5.1 源端 DDR 带宽

发送端 RNIC 需要通过 PCIe DMA read 从源 DDR 读取 payload。

如果源端 DDR 带宽不足,或者数据所在 NUMA 节点距离 RNIC 太远,会影响发送性能。

常见问题:

  • buffer 分配在错误 NUMA node;
  • RNIC 挂在 CPU socket 0,但数据在 socket 1;
  • 跨 UPI/QPI 访问导致额外延迟和带宽损耗;
  • CPU 同时大量访问内存,与 RNIC DMA 竞争内存带宽;
  • hugepage、page pinning、IOMMU translation 影响性能。

优化方向:

  • NUMA affinity;
  • 让应用线程、RNIC、内存位于同一 NUMA node;
  • 使用 hugepage;
  • 合理配置 IOMMU;
  • 减少非必要内存 copy;
  • 避免 CPU 和 RNIC 同时争抢同一内存区域。

5.2 PCIe 带宽与 PCIe transaction 开销

RNIC 作为 PCIe 设备,payload 必须经过 PCIe。

发送端路径:

1
Host DDR -> PCIe DMA Read -> RNIC

接收端路径:

1
RNIC -> PCIe DMA Write -> Host DDR

PCIe 可能成为瓶颈,尤其是在:

  • 400G / 800G NIC;
  • 单机多张 RNIC;
  • RNIC 与 GPU 同时走同一个 PCIe switch;
  • GPUDirect RDMA;
  • 小包高 PPS;
  • PCIe read completion latency 较高;
  • PCIe ACS / IOMMU 配置不当。

需要关注:

  • PCIe generation;
  • lane 数量;
  • NUMA 拓扑;
  • PCIe switch oversubscription;
  • read request size;
  • max payload size;
  • max read request size;
  • relaxed ordering;
  • DDIO;
  • IOMMU passthrough;
  • peer-to-peer DMA 能力。

5.3 RNIC 内部瓶颈

RNIC 内部不是无限快的。

常见内部瓶颈包括:

RNIC 模块 可能瓶颈
DMA Engine PCIe read/write outstanding 不足
WQE Fetch Engine descriptor fetch 延迟
QP Context Cache QP 数量大导致 cache miss
MR Translation Cache MTT/MPT miss
Packetizer 小包 PPS 压力
Reorder Buffer 乱序或重传压力
Completion Engine CQE 写入过多
Congestion Control Engine rate limiter 粒度不足
RX Buffer microburst 吸收能力有限

典型优化包括:

  • 减少 QP 数量;
  • 使用 shared receive queue;
  • 合理设置 CQ moderation;
  • 使用 unsignaled WQE;
  • batch post WQE;
  • 使用 inline data 优化小消息;
  • 避免过小 MTU;
  • 避免过度碎片化的 SGE;
  • 减少 MR 数量或提高 MR cache 命中率。

5.4 NIC 端口带宽

NIC 端口速率是显性瓶颈。

常见端口速率包括:

  • 25G;
  • 50G;
  • 100G;
  • 200G;
  • 400G;
  • 800G。

但端口 line rate 不等于应用可用吞吐。还需要扣除:

  • Ethernet header;
  • IP header;
  • UDP header;
  • BTH/RETH/AETH;
  • ICRC;
  • IFG;
  • preamble;
  • FEC;
  • small message overhead;
  • ACK/CNP/control traffic。

对于小消息场景,瓶颈可能不是带宽,而是:

1
2
3
4
5
PPS
doorbell rate
WQE processing rate
CQE processing rate
PCIe transaction rate

5.5 交换机 buffer 与队列

RoCEv2 网络里,交换机 buffer 是关键资源。

典型问题:

  • incast;
  • many-to-one;
  • all-to-all;
  • microburst;
  • hash polarization;
  • ECMP 不均衡;
  • PFC headroom 不足;
  • ECN threshold 过高或过低;
  • lossless queue 与 lossy queue 混用;
  • PFC pause 扩散。

交换机侧需要关注:

  • per-port buffer;
  • shared buffer;
  • headroom buffer;
  • PFC threshold;
  • ECN min/max threshold;
  • WRED 曲线;
  • queue scheduling;
  • buffer occupancy telemetry;
  • PFC pause counter;
  • ECN mark counter;
  • packet drop counter;
  • CNP counter。

5.6 Leaf-Spine Fabric 瓶颈

在数据中心网络中,RDMA 流量经常是东西向流量。AI 训练、分布式存储和 HPC 场景中,大量节点之间会产生 all-to-all 或 incast 模式。

可能的 fabric 瓶颈包括:

  • 上行 oversubscription;
  • ECMP hash 不均;
  • elephant flow 占用路径;
  • flowlet 不稳定;
  • spine 到 leaf 热点;
  • PFC 在多跳网络中扩散;
  • 不同优先级队列抢占资源;
  • telemetry 不足导致问题不可见。

工程上要重点观察:

1
2
3
4
5
6
ECN mark 是否集中在某些队列
PFC pause 是否向上游扩散
是否存在长期 pause
是否出现 drop
是否存在路径不均衡
是否存在 elephant flow

5.7 目标端 DDR 与 PCIe 写入瓶颈

接收端并不是被动无限吸收数据。

RDMA Write 最终要写入 Host B DDR。目标端可能成为瓶颈:

  • 目标 DDR 带宽不足;
  • 多个发送端同时写一个接收端;
  • incast 导致 RNIC RX buffer 压力;
  • PCIe write 带宽不足;
  • 目标内存跨 NUMA;
  • 应用消费速度慢;
  • ring buffer 设计不合理;
  • cache coherency 与 CPU 读取冲突。

尤其在 many-to-one 场景中,瓶颈很可能不是网络,而是:

1
Receiver RNIC -> PCIe -> Target DDR

5.8 Completion 与 CPU 侧瓶颈

虽然 RDMA 数据面绕过 CPU,但控制面和完成处理仍然消耗 CPU。

可能瓶颈包括:

  • 应用 poll CQ 过频繁;
  • CQE 过多;
  • signaled WQE 过多;
  • completion vector 绑定不合理;
  • CPU core 与 RNIC NUMA 不匹配;
  • busy polling 消耗 CPU;
  • cache miss;
  • 多线程竞争 CQ/QP。

优化方向:

  • 使用 unsignaled WQE;
  • completion batching;
  • CQ moderation;
  • 合理绑定 CPU affinity;
  • 减少共享 CQ 竞争;
  • 控制 QP 数量;
  • 使用高效的用户态框架,例如 UCX、DPDK-style polling、SPDK 等。

5.9 一张瓶颈定位表

位置 典型瓶颈 观察指标
Source DDR 内存带宽、NUMA memory bandwidth、remote NUMA access
PCIe TX side DMA read 带宽、read latency PCIe throughput、read completion latency
RNIC TX WQE、QP cache、packetizer NIC counters、QP cache miss、PPS
NIC port line rate、PPS port utilization、packet size
Leaf switch buffer、ECN、PFC ECN marks、PFC pause、drops
Spine oversubscription、hash imbalance link utilization、ECMP distribution
Receiver RNIC RX buffer、reorder、DMA write RX drops、CNP、PCIe write
Target DDR 写入带宽、NUMA memory bandwidth、application consume rate
CPU/CQ completion handling CPU utilization、CQ polling cost

结语

RDMA 的本质不是“网络协议更快”,而是把通信模型从 socket 字节流变成了基于注册内存、队列和 RNIC offload 的远端内存访问模型。

可以用一句话概括:

1
2
3
4
应用通过 QP/WQE 描述通信操作,
RNIC 通过 DMA 直接访问两端注册内存,
RoCEv2 负责把 RDMA transport 承载在 UDP/IP/Ethernet 上,
网络通过 PFC、ECN、CNP、DCQCN 等机制尽量维持低丢包和低尾延迟。

对于传统网络工程师,理解 RDMA 时最重要的是把视角从“包怎么转发”扩展到“数据如何从一端 DDR 进入另一端 DDR”。

RDMA 性能问题也不只在网络上,而是贯穿:

1
2
3
4
5
6
7
8
9
DDR
PCIe
RNIC
NIC port
Leaf-Spine fabric
PFC/ECN
目标端 PCIe
目标端 DDR
应用消费模型

只有把主机、RNIC 和网络 fabric 放在同一条数据通路中分析,才能真正理解 RDMA 网络的性能边界和工程复杂度。