RDMA 是什么、怎么用?
GPUDirect 又省掉了什么?

英文问法What is RDMA and why is it faster than TCP? · Walk me through the verbs workflow. · What does GPUDirect RDMA do? · InfiniBand vs RoCE?

考过面经:NVIDIA Research System AI 实习 2024 一面("先问了一些基础知识,包括分布式训练,RDMA的工作流程和编程,网络的一些知识",Pass,1p3a 1060932)

先弄清楚:每个概念是什么

RDMA
网卡直接读写对端机器的内存,对端 CPU 和 OS 都不参与。TCP 两端都要经过 kernel 拆包、再拷进 app buffer。RDMA 的通道建好后,app 直接给网卡下 work request(kernel bypass),数据从 app buffer 直接落进对端 buffer(zero copy)。
Memory registration
用之前先把 buffer 登记给网卡:pin 住页面,把虚拟→物理地址表写进网卡,拿到 lkey / rkey。网卡按物理地址做 DMA,所以页面不能被 swap 或迁移(PyTorch DataLoader 的 pin_memory=True 同理)。对端只有拿到 rkey 才能远程读写这块内存。
InfiniBand vs RoCE
同一套 verbs API。InfiniBand 是专用网络,链路层自带 credit-based flow control 管拥塞;RoCE 把 RDMA 跑在 Ethernet 上,要靠 PFC(Priority Flow Control)做成 lossless。
GPUDirect 家族
P2P:同机 GPU 之间直接 copy 或 load/store,走 NVLink 或 PCIe。RDMA:网卡直接读写 GPU memory,不经 host memory 中转。Storage:NVMe / NVMe-oF 直接 DMA 进 GPU memory,省掉 CPU 的 bounce buffer。

看图:三种数据路径,verbs 流程

TCP两端都经过 kernelGPU memoryhost bufferkernel bufferNIC网络NICkernel bufferhost bufferGPU memoryRDMAkernel bypassGPU memoryhost bufferNIC网络NIChost bufferGPU memory跳过 kernel跳过 kernelGPUDirect RDMANIC 直接读写 GPUGPU memoryNIC网络NICGPU memory不经过 host跳过 kernel跳过 kernel不经过 host每端多拷 2 次每端多拷 1 次没有多余拷贝发送端接收端多出来的拷贝(cudaMemcpy、CPU copy)NIC 的 DMA 和网线传输,不算拷贝
图 1:把一块 gradient 从一台机器的 GPU 送到另一台的 GPU。TCP 每端多拷 2 次,RDMA 跳过 kernel 只剩 GPU ↔ host 这 1 次,GPUDirect RDMA 把这 1 次也省掉。
appkernelNIC① 打开设备,分配 PDprotection domain② register memorypin 页面,拿 lkey / rkey③ 建 CQ 和 QP带外交换 rkey,QP 走到 RTS④ post WRsend / recv、RDMA write / read⑤ poll CQ拿完成事件一次性准备每条消息④ ⑤ 每条消息重复,不进 kernel;用完按相反顺序销毁
图 2:每一行箭头表示这一步要经过谁。①–③ 只在开始做一次,要经过 kernel。每条消息只做 ④ ⑤,不进 kernel,这就是 kernel bypass。

30 秒回答

RDMA lets a NIC read or write a remote host's memory directly. After a one-time setup the application posts work requests straight to the NIC, so the data path bypasses the kernel, makes no intermediate copies, and leaves the remote CPU out. Memory must be registered first, which pins it and gives the NIC keys. InfiniBand has credit-based flow control built in; RoCE runs the same verbs over Ethernet and relies on PFC to be lossless. GPUDirect RDMA lets the NIC DMA straight to and from GPU memory, skipping the host bounce buffer. NCCL uses NVLink inside a node and GPUDirect RDMA across nodes.

关键流程

数据路径:GPUDirect RDMA 省了什么

没有 GDR 时两端各多一次 GPU ↔ host buffer 的拷贝,见图 1。前提:GPU 和 NIC 挂在同一个 PCIe switch 下,并加载 nvidia-peermem(或用 DMA-BUF)。GDR 走 PCIe peer-to-peer,绕到 CPU root complex 就慢甚至不支持,PCIe ACS 开着也会这样绕,NCCL 文档说可能大幅变慢甚至 hang。

verbs 编程流程(NVIDIA 原题)

  1. 打开设备,分配 protection domain(PD)
  2. register memory:pin 页面,拿到 lkey / rkey
  3. 建 CQ 和 QP;带外交换 QP number、地址、rkey;QP 走 INIT → RTR → RTS
  4. post work request:send / recv,或 RDMA write / read
  5. poll CQ 拿完成事件;用完按相反顺序销毁
链路(H100 一代)每 GPU 带宽口径
HBM(H100 SXM)3.35 TB/s显存本身
NVLink 4 + NVSwitch900 GB/s双向合计,机内
PCIe Gen5 x16128 GB/s双向合计
ConnectX-7 IB NDR400 Gb/s = 50 GB/s单向,跨机;DGX H100 配 8 张,对应 8 GPU

手算例子:TP 为什么不跨机

一次 TP all-reduce 的 activation \(b\cdot s\cdot h\cdot 2\) bytes,取 \(b=1, s=4096, h=8192\):67 MB。\(t=8\) 的 ring 每卡发 \(2\cdot\tfrac78\cdot 67\) ≈ 117 MB。

必答点

追问

two-sided 和 one-sided 有什么区别?

send / recv 是 two-sided,对端必须先 post recv buffer。RDMA write / read 是 one-sided,对端 CPU 不知情,只需事先给出地址和 rkey(write with immediate 才会通知对端)。

怎么确认 GPUDirect RDMA 真的生效?

NCCL_DEBUG=INFO NCCL_DEBUG_SUBSYS=NET 看选了哪种 transport,没有 IB 时会回退到每次收发都经 kernel 的 IP sockets(NCCL_IB_DISABLE=1 可强制)。再查 lsmod | grep nvidia-peermem,NCCL_NET_GDR_LEVEL 决定 GPU 与 NIC 隔多远还用 GDR(PIX / PXB / PHB / SYS)。

来源NVIDIA RDMA Aware Networks Programming User Manual v1.7 Introduction(p.10)、§2.1–2.4(pp.15–18)、§3.1(pp.20–21)、§3.3.4(p.22)、§3.4(pp.24–25)· NVIDIA GPUDirect(Storage、RDMA、P2P)· GPUDirect RDMA docs §1 · NCCL Environment Variables(NCCL_NET_GDR_LEVEL、NCCL_IB_DISABLE)、GPU troubleshooting(GPU-to-NIC、ACS)· H100 specs · NVLink specs · DGX H100 User Guide Table 1 · PyTorch Performance Tuning Guide(pin_memory)