一、 一句话说清 RDMA
|--------|------------------------------------|--------------------------|
| | 传统网络 | RDMA |
| 数据路径 | App → 内核 → 网卡 → 网络 → 网卡 → 内核 → App | App → 网卡 → 网络 → 网卡 → App |
| CPU 参与 | 每次拷贝都打断 CPU | 零拷贝 + CPU 旁路 |
| 延迟 | 10--50 μs | 1--3 μs |
| CPU 占用 | ~70% | **<10%** |
一句话: RDMA 让网卡直接读你的内存,不经过操作系统。

- RDMA工作原理是怎么样的?

红色路径为传统TCP/IP数据传输路径,发送端APP需将待传输数据写入OS的buffer,然后经过CPU拷贝到网卡的buffer,网卡将数据处理成报文,经过中间网络发送到接收端。接收端网卡收到报文数据后,先缓存到buffer中,然后OS从网卡buffer取数据到OS的缓存,最后才是接收端APP从OS的缓存中获取数据。可以看到整个过程需要CPU强参与,并且数据经过多次拷贝。
那么RDMA数据拷贝无需CPU参与,发送端具备RDMA协议栈的HCA网卡直接从APP中获取待传输数据,封装成报文通过中间网络发送到接收端,接收端HCA直接将数据传递给APP,避免了多次数据拷贝,有效提升性能。
三、 为什么 AI 训练离不开它
- NVIDIA DGX、华为 Atlas 900、Google TPU Pod------万卡互联全用 RDMA

- AllReduce 一次梯度同步要传几 GB,TCP 扛不住(慢启动 + 队头阻塞)
- 存储侧:NVMe over Fabrics 也是 RDMA

- 云厂商:阿里神龙、AWS EFA、华为云弹性网络

所以:搞懂 RDMA = 搞懂 AI 基础设施的底层语言。
四、 实验环境
|------------|----------------------------------------------|
| 项目 | 要求 |
| 宿主机 | Windows |
| 虚拟化 | VMware |
| 虚拟机 | 2 台 Ubuntu 22.04 Server(2 vCPU / 2GB RAM 就够) |
| 网络 | 两台 VM 网卡设为"内部网络"(Internal Network) |
| RDMA 软件 | rdma-core、perftest、iproute2 |
网络规划:
|------------|-------------|----------------|
| 节点 | 主机名 | IP |
| Node-A | rdma-srv | 192.168.95.128 |
| Node-B | rdma-cli | 192.168.95.130 |
五、 环境搭建
两台 VM 都执行:
1. 配静态 IP
2. 验证互通
ping 192.168.95.130 # 从 Node-A 执行
3. 安装 RDMA 工具链sudo apt updatesudo apt install -y rdma-core ibverbs-utils perftest iproute2 \
libibverbs-dev librdmacm-dev
4. 加载 Soft-RoCE 模块sudo modprobe rdma_rxe
5. 创建 RXE 设备,绑定到你的网卡(通常是 enp0s3)sudo rdma link add rxe_0 type rxe netdev enp0s3
6. 验证
rdma link show# 应看到:rxe_0/1 state ACTIVE physical_state LINK_UP
⚠️ 踩坑预警:
- rdma link add 报错 File exists → 说明已创建过,先 rdma link del rxe_0 再试
- state DOWN → 检查网卡名对不对,ip link show 确认
- Ubuntu 24.04 内核自带 rdma_rxe,22.04 需 apt install linux-modules-extra-$(uname -r)
六、 跑第一个 RDMA 测试
先开服务端(Node-A):
ib_send_bw -d rxe_0 -x 2 --report_gbits
再开客户端(Node-B):
ib_send_bw -d rxe_0 -x 2 --report_gbits 192.168.95.128
预期输出:
看到数字就对了!哪怕只有 0.57 Gbps(≈71 MB/s),你跑通的也是真正的 RDMA 协议栈。

七、 为什么只有 71 MB/s?
|------------|------------------------------------|
| 原因 | 解释 |
| 虚拟机 CPU 瓶颈 | Soft-RoCE 用 CPU 模拟网卡,不是真硬件 offload |
| 单 QP | 默认只开 1 个 Queue Pair,真机开 8--32 个并行 |
| MTU 1500 | 默认小包,真机用 4200/9000 |
| 内部网络带宽 | VirtualBox 内部网络走宿主机内存,不是真网卡 |
真机对比 :NVIDIA ConnectX-6 + 100GbE 交换机 → 100 Gbps 轻松跑满。
所以:这篇的价值不是性能,是让你看懂协议长什么样。
八、 抓包看透 RoCEv2(Wireshark 逐字段)
新终端抓包(Node-A):
sudo tcpdump -i enp0s3 -w rdma.pcap udp port 4791
另开终端重跑ib_send_bw,几秒后 Ctrl+C。
Wireshark 打开 rdma.pcap**,过滤**udp.port == 4791。
你会看到三类包滚动:
|----------------|----------------|----------------|
| 类型 | Opcode | 含义 |
| RC Send First | 0 | 大消息的第一个分片 |
| RC Send Middle | 1 | 中间分片(只有 PSN 变) |
| RC Send Last | 2 | 最后一个分片(要求 ACK) |
| RC ACK | 17 | 接收端确认 |
点开第一个包,展开 InfiniBand**→** BTH**(Base Transport Header)**:
|------------|----------------|------------------|
| 字段 | 值 | 什么意思 |
| Opcode | 0 (Send First) | 这是 64KB 消息的第 1 段 |
| PSN | 858106 | 包序列号,每包 +1 |
| Dest QP | 0x0011 | 对端队列对编号 |
| Dest Port | 4791 | RoCEv2 固定 UDP 端口 |
1、 RC Send First 报文解析
双击第一个数据包,展开 BTH 头部:
• Opcode = 0 (SEND First) → 大消息的第一个分片
• PSN = 858106 → 包序列号,每个包递增1
• Dest QP = 0x0011 → 对端队列对编号
• Dest Port = 4791 → RoCEv2 固定端口
64KB消息 → MTU 1024 → 拆成64个包:First + 62×Middle + Last

2、 RC Send Middle 和 Last
连续滚动,你会看到:
• 一堆 RC Send Middle(仅PSN变化)
• 最后一个包:RC Send Last
展开 Last 包的 BTH:
✅ Acknowledge Request = 1(要求接收端回复ACK)
累积确认:收完一整条消息才回一个ACK,节省带宽


3、 RC Acknowledge 报文
找到 ACK 报文(Opcode = 17):
• PSN = 858169(等于发送端Last包的PSN)
• 含义:"截止到此PSN,我都收到了"
展开 AETH 扩展头:
• Syndrome = 31(正常ACK)
• Credit Count = 31(我还有31个缓冲槽,继续发)

九、 64KB 怎么拆成 64 个包
64 KB 消息 ÷ MTU 1024 B = 64 个 RDMA 报文
First\] → \[Middle\] × 62 → \[Last (AckReq=1)
↓
ACK ← 接收端
- First 包:Opcode=0,带 BTH 头
- Middle 包:Opcode=1,只变 PSN
- Last 包:Opcode=2,AckReq=1(要求确认)
- ACK 包:Opcode=17,PSN=858169(等于 Last 的 PSN),Syndrome=31(正常)
一次 64KB 消息 = 64 个数据包 + 1 个 ACK。服务端 CPU 只在最后 poll CQ,中间全由网卡硬件完成。

十、 整个交互流程图
客户端 服务端
| |
|---First------------------------->|
|---Middle × 62 ------------------>|
|---Last (AckReq=1)-------------->|
| | (网卡收完,写内存,
| | CPU 最后 poll CQ)
|<--ACK: PSN=858169, Credit=31----|
这就是 RDMA 的精髓:中间过程 CPU 完全不介入。
十一、 下一步
你已经做到的事:
- ✅ 在一台笔记本上跑通 RDMA
- ✅ 用 Soft-RoCE 模拟真实 RDMA 网卡
- ✅ 抓包看懂 RoCEv2 报文结构
- ✅ 理解 QP / PSN / BTH / ACK 机制
下一步可以学:
- PFC(Priority Flow Control):为什么 AI 交换机要"按优先级暂停"
- ECN + DCQCN:拥塞控制怎么在交换机+网卡之间闭环
- NCCL + AllReduce:GPU 梯度同步怎么用 RDMA
- 真机环境:ConnectX-5/6 + 博通交换机