RDMA 深入 —— InfiniBand、RoCE 与 iWARP

第五章 5.8 已经讲了 AI 集群里 IB / RoCE 的”应用层”。本篇深入协议——RDMA 的 verbs、QP / WQE、IB / RoCE / iWARP 的协议差异,以及实际调优。

为什么 RDMA 这么重要

1
2
3
4
5
6
7
8
9
传统 socket TCP:
应用 → write(fd) → kernel → TCP/IP 栈 → 网卡 → 链路
延迟 5-50 μs(同机房)
CPU 占用:每包都过 kernel

RDMA:
应用 → ibv_post_send → 网卡(DMA 直接读应用内存)→ 链路
延迟 1-5 μs
CPU 0 占用(除了发起请求那一下)

RDMA 三大特性:

graph TB
  R1[Kernel Bypass
不过 OS 内核] R2[Zero Copy
不拷贝数据] R3[Direct Memory Access
网卡读写应用内存] R1 --> P[低延迟 + 低 CPU] R2 --> P R3 --> P

三种 RDMA 实现

graph TB
  RDMA[RDMA]
  RDMA --> IB[InfiniBand
专用物理 + 链路 + 网络] RDMA --> ROCE[RoCE
跑在以太网上] RDMA --> IWARP[iWARP
跑在 TCP/IP 上]
InfiniBand RoCE v2 iWARP
物理层 IB 专用 以太网 以太网
链路层 IB 以太网 + 无损 以太网
网络层 IB IBA UDP/IP TCP/IP
传输层 IBA IBA iSER over TCP
流控 Credit-based 无损 PFC + ECN TCP 重传
延迟 1-2 μs 2-5 μs 5-15 μs
跨子网 经路由器 UDP 路由可达 TCP 路由可达
厂家 NVIDIA Mellanox 主导 NV / BCM / Marvell Chelsio 主导
市场 AI / HPC 主流 AI / 云存储 增长 金融 / 存储 小众

InfiniBand 协议栈

graph TB
  APP[应用]
  APP --> VERBS[Verbs API
libibverbs] VERBS --> CORE[IB Core
kernel] CORE --> HW[网卡硬件
HCA] HW --> LINK[IB 链路层
credit 流控] LINK --> PHY[IB 物理层
SerDes / NRZ / PAM4]

HCA(Host Channel Adapter)= IB 网卡。每个 HCA 有:

1
2
3
GUID(Globally Unique ID):     全局唯一
LID(Local ID): 本地子网内 16-bit
GID(Global ID): 跨子网 128-bit(类似 IPv6 地址)

IB 子网管理器

每个 IB 网络有一个 SM(Subnet Manager)——通常运行在 IB 交换机上:

1
2
3
4
5
SM 职责:
- 自动发现拓扑
- 分配 LID
- 配置交换机路由表
- 监控链路状态

这是 IB 和以太网最大的不同——IB 自带”自动配置”,以太网要靠 BGP / 自配置协议

verbs API:编程模型

RDMA 应用通过 libibverbs 编程。核心概念:

graph TB
  PD[Protection Domain
保护域] CQ[Completion Queue
完成队列] QP[Queue Pair
SQ + RQ] MR[Memory Region
注册内存] WR[Work Request
请求] PD --- QP PD --- MR QP --- CQ WR --> QP
概念 作用
PD(Protection Domain) 保护域,隔离不同应用的资源
MR(Memory Region) 注册的内存——网卡知道 va→pa 映射
QP(Queue Pair) 一对 Send Queue + Receive Queue
CQ(Completion Queue) 操作完成事件队列
WR(Work Request) send/recv/read/write 请求
WC(Work Completion) WR 完成事件

QP 类型

1
2
3
4
5
RC(Reliable Connection):可靠连接,类似 TCP
UC(Unreliable Connection):不可靠连接(少用)
UD(Unreliable Datagram):不可靠数据报,类似 UDP
XRC(eXtended RC): 共享 QP 的扩展版(多对多)
DCT(Dynamic Connect): 动态连接,万卡集群可扩展

RC 是最常用的——MPI / NCCL / Verbs 应用绝大多数用 RC。

四种核心操作

1
2
3
4
SEND / RECV:       双方都参与(双端模式)
RDMA WRITE: 发起方写到对方内存(单端,对方 CPU 不参与)
RDMA READ: 发起方读对方内存
ATOMIC: 远端原子操作(CAS / FAA)

RDMA WRITE/READ 是真正的”零开销”——对方 CPU 完全不知道。

1
2
3
4
5
6
7
8
9
// 简化的 RDMA WRITE 示例(伪代码)
struct ibv_send_wr wr = {
.opcode = IBV_WR_RDMA_WRITE,
.sg_list = &local_addr,
.num_sge = 1,
.wr.rdma.remote_addr = remote_addr,
.wr.rdma.rkey = remote_key,
};
ibv_post_send(qp, &wr, &bad_wr);

RoCE 详解

RoCE = RDMA over Converged Ethernet

graph TB
  subgraph V1["RoCE v1"]
    L1V1[Ethernet]
    L2V1[IB 传输层]
    L1V1 --- L2V1
  end
  subgraph V2["RoCE v2"]
    L1V2[Ethernet]
    L2V2[IP]
    L3V2[UDP 4791 端口]
    L4V2[IB 传输层]
    L1V2 --- L2V2 --- L3V2 --- L4V2
  end

RoCE v1:链路层 RDMA,只能同 LAN 内(无 IP 头,不能路由)
RoCE v2:UDP 4791 端口承载 IB 传输层——可以跨子网路由

现在大家说 RoCE 默认是 v2。

RoCE 的”无损”挑战

IB 物理层就是无损的(credit 流控);以太网默认会丢包,RoCE 必须靠无损以太网

1
2
3
要素 1:PFC(Priority Flow Control,链路级背压)
要素 2:ECN(Explicit Congestion Notification,端到端拥塞)
要素 3:DCQCN(Data Center QCN,拥塞控制算法)

详细在 无损网络与拥塞控制 一篇展开。

iWARP 简介

iWARP(Internet Wide Area RDMA Protocol):

1
2
3
4
5
6
7
8
9
10
11
RDMA 跑在 TCP 之上:
IP / TCP / DDP / MPA / RDMAP / 应用

优点:
- 利用 TCP 重传,不需要无损以太网
- 跨数据中心可达

缺点:
- 延迟大(10-15 μs)
- 性能不如 RoCE
- 厂家少(Chelsio / Intel)

iWARP 主要在金融、存储应用上有少量部署——AI 不用 iWARP

GPUDirect RDMA

普通 RDMA 是 CPU 内存 ↔ CPU 内存。AI 训练要 GPU 内存 ↔ GPU 内存——这就是 GPUDirect RDMA:

graph LR
  G1[GPU A 显存] --> NIC1[HCA A]
  NIC1 --> NIC2[HCA B]
  NIC2 --> G2[GPU B 显存]
  
  CPU1[CPU A] -.- X[不参与]
  CPU2[CPU B] -.- X

工作原理:

1
2
3
4
1. GPU 显存 BAR 暴露给 PCIe 总线
2. 网卡 DMA 直接读写 GPU 显存(peer-to-peer over PCIe)
3. 不经过 CPU 内存
4. NCCL / MPI 等库自动启用

GPUDirect RDMA 让 GPU 跨节点通信延迟从 ~10 μs 降到 ~3 μs。这是 H100/B200 集群训练的标配。

配置要点

1
2
3
4
5
6
7
8
9
10
11
12
13
# 启用 GPUDirect(BlueField / ConnectX)
modprobe nvidia_peermem

# 验证
lsmod | grep nv_peer_mem
ibv_devinfo | grep -A5 active

# NCCL 测试(跨节点)
mpirun -np 16 -hostfile hosts ./all_reduce_perf -b 1G -e 16G -f 2 -g 8

# GDRCOPY(小消息加速)
git clone https://github.com/NVIDIA/gdrcopy
make install

性能数字直觉

操作 延迟 带宽
IB ConnectX-7 RC SEND(小消息) ~1 μs -
IB RDMA WRITE 4 KB ~2 μs -
IB RDMA READ 4 KB ~3 μs -
IB RC bulk write 1 MB - ~50 GB/s(400G)
RoCE v2 RC SEND ~2-3 μs -
iWARP TCP write 4 KB ~10 μs -
TCP socket 4 KB ~30-50 μs -
GPUDirect RDMA WRITE 4 KB ~3 μs(跨节点) -

实测带宽:

1
2
3
ConnectX-7 400G 单口理论:   400 Gbps = 50 GB/s
PCIe 5.0 ×16 单向: 64 GB/s
实测 ib_write_bw: ~48 GB/s(达到光速 96%)

RDMA 的应用栈

graph TB
  APP[应用]
  APP --> CHOICE{选择}
  CHOICE --> VERBS[Verbs
底层 API] CHOICE --> MPI[MPI
HPC 标准] CHOICE --> NCCL[NCCL
AI 集合通信] CHOICE --> UCX[UCX
统一通信层] CHOICE --> NVMEoF[NVMe-oF
存储] CHOICE --> GPFS[GPFS / Lustre
文件系统] VERBS --> HW[HCA] MPI --> VERBS NCCL --> VERBS UCX --> VERBS NVMEoF --> VERBS GPFS --> VERBS

直接写 verbs 的应用很少——大部分通过 MPI / NCCL / UCX 这些上层库。

MPI(Message Passing Interface)

1
2
3
4
5
HPC 经典通信库:
- 1990s 起标准化
- OpenMPI / MPICH / Intel MPI
- 集合操作:AllReduce / AllGather / Broadcast 等
- 后端可对接 IB / RoCE / TCP

NCCL(NVIDIA Collective)

1
2
3
4
5
专为 GPU 集群优化:
- 拓扑感知(NVLink / IB / PCIe)
- GPU-to-GPU 直接通信
- PyTorch / JAX 默认后端
- 类似版本:RCCL(AMD)、HCCL(华为)

UCX(Unified Communication X)

1
2
3
4
HPC 跨厂家通信抽象层:
- 自动选最佳传输路径(IB / RoCE / SHM / TCP)
- MPI 后端常用
- OpenMPI 默认 UCX

RDMA 的”老坑”

坑 1:MTU 不一致导致丢包

1
2
3
# IB 标准 MTU 4096,但端到端必须一致
ibportstate <port> mtu <2048|4096>
sysctl -w net.core.rmem_max=...

坑 2:QP 数量爆炸

1
2
3
4
5
6
n 节点全互联:n*(n-1)/2 个 RC QP
1000 节点:50 万 QP
每 QP HCA 需要资源 → 内存爆炸

→ 用 DCT(Dynamic Connect)或 XRC 减少 QP
→ NCCL 自动处理

坑 3:RoCE PFC storm

1
2
3
4
5
6
7
PFC 配置错 → 整个网络 PAUSE 蔓延
→ 全网吞吐崩

诊断:
- 看交换机 PFC 计数器异常
- 看 mlxlink / ibstat
- 看 NCCL 日志

坑 4:内存注册慢

1
2
3
ibv_reg_mr 注册大内存:耗时
→ ODP(On-Demand Paging)让网卡懒注册
→ 或者预先注册大块内存重用

坑 5:MR 限制

1
2
3
HCA 单卡能注册的 MR 数和大小有限
→ 大模型训练时 MR 数过多 → 注册失败
→ 用 MR cache / 大段注册

verbs 编程的几个调试命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# HCA 列表
ibv_devices
ibv_devinfo
ibv_devinfo mlx5_0

# 端口状态
ibstat
ibstatus

# 性能测试
ib_send_bw -d mlx5_0 server_ip
ib_send_lat -d mlx5_0 server_ip
ib_write_bw -d mlx5_0 -F server_ip
ib_read_bw -d mlx5_0 -F server_ip

# 跑 RoCE(指定 GID)
ib_send_bw -d mlx5_0 -i 1 -x 3 server_ip # GID index 3 通常是 RoCE v2

# 路径追踪
ibtracert <src_lid> <dst_lid>

# QP 状态
ibv_devinfo -v
mlnx_perf -i mlx5_0

调优清单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 1. 中断绑定到 CPU NUMA 同侧
echo 0 > /proc/irq/<irq>/smp_affinity_list

# 2. NUMA 内分配内存
numactl --membind=0 ./app

# 3. 大页内存(减少 TLB miss)
echo 2048 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

# 4. CPU 高性能模式
cpupower frequency-set -g performance

# 5. 关闭 C-State
cpupower idle-set -D 0

# 6. PCIe ACS 关闭(GPUDirect 必需)
setpci -s <BDF> ECAP_ACS+0x6.w=0:1f0

# 7. ConnectX 性能配置
mlxconfig -d <DEV> set PCI_WR_ORDERING=1
mlxconfig -d <DEV> set CQE_COMPRESSION=1

选 IB 还是 RoCE?

场景 推荐 原因
万卡 AI 训练 InfiniBand 默认稳定 + SHARP
千卡 AI 训练 IB / RoCE 都行 两者差距不大
中小集群 RoCE 便宜 + 以太网兼容
云存储后端 RoCE 与现有以太网融合
HPC 计算 InfiniBand 默认
跨厂家集群 RoCE IB 厂家锁定

一些实战经验

1
2
3
4
5
6
7
8
9
10
11
12
13
1. 万卡级训练:     IB + ConnectX-7/8 + Quantum-2
2. 千卡级训练: IB 或 RoCE 都行
3. 300+ 卡推理: RoCE 100/200G 充分
4. 单租户私有集群: IB 部署便利
5. 云租户: RoCE 与以太网共存

调优时间预算:
IB: 1-2 周配置 + 1 周调优
RoCE: 1-2 月配置 + 持续调优 PFC/ECN

故障排查:
IB: 工具齐全(ibtools 套件)
RoCE: 要拼以太网工具 + IB 工具

小结

  • RDMA 三大特性:kernel bypass、zero copy、direct memory access
  • IB / RoCE / iWARP 三种实现,AI 集群只用前两个
  • verbs API 暴露 QP / MR / CQ / WR 等概念
  • GPUDirect RDMA 让 GPU 跨节点直接通信
  • IB 自带子网管理 + credit 流控,RoCE 要靠 PFC/ECN
  • NCCL / MPI / UCX 是上层最常用的 RDMA 应用接口
  • 调优要从 NUMA、大页、中断绑定全面着手

下一篇讲数据中心拓扑——Spine-Leaf、Fat-Tree、Dragonfly。