3. 核心技术原理:RDMA、GPUDirect RDMA、NVMe over Fabrics
要理解 GPU Direct 存储访问,必须先厘清三条技术主线:RDMA 解决“CPU 不参与数据搬运”的问题,GPUDirect RDMA 解决“数据绕过 GPU 内存直达显存”的问题,而 NVMe over Fabrics 解决“存储协议在网络上高效传输”的问题。三者层层叠加,才构成 GPU 直连存储的完整数据通路。
3.1 RDMA:内核旁路与零拷贝
传统 TCP/IP 网络路径中,数据从网卡到应用需要经过内核协议栈、Socket 缓冲区、用户态缓冲区多次拷贝,CPU 中断处理频繁。RDMA(Remote Direct Memory Access)的核心思想是:让网卡(RNIC)直接读写远端内存,绕过操作系统内核。
RDMA 提供三种典型操作:
- Send/Receive:类似消息传递,由接收端预先发布缓冲区描述符。
- RDMA Read:主动从远端内存读取数据,远端 CPU 无感知。
- RDMA Write:主动向远端内存写入数据,可附带立即数。
实现 RDMA 需要三个关键机制:
- 内核旁路(Kernel Bypass):应用通过 Verbs API 直接与网卡交换命令,不经过系统调用。
- 零拷贝(Zero-Copy):数据在网卡与用户缓冲区之间直接 DMA 传输,无需中间缓冲。
- 卸载(Offload):可靠传输、乱序重组、流量控制全部由网卡硬件完成。
关键概念:RDMA 的“远程直接内存访问”本质是让网卡成为 DMA 引擎。CPU 只负责发布工作请求(Work Request),完成后通过完成队列(Completion Queue)获知结果,数据路径上 CPU 完全不参与。
3.2 GPUDirect RDMA:打通网卡到显存的直通路径
在 GPUDirect RDMA 出现之前,即使网络使用 RDMA,数据到达 GPU 仍需经过“网卡 → CPU 内存 → PCIe → 显存”的路径,其中 CPU 内存中转造成额外延迟和带宽浪费。GPUDirect RDMA 的核心突破是:允许第三方 PCIe 设备(如 InfiniBand 网卡、NVMe 控制器)直接访问 GPU 显存地址。
其实现依赖 NVIDIA 提供的 nvidia-peermem 内核模块。该模块将 GPU 显存物理页面注册到内核的 DMA 映射框架中,使外部设备能够获取 GPU 显存的总线地址(Bus Address),从而发起 DMA 传输。
# 加载 GPUDirect RDMA 支持模块
modprobe nvidia-peermem
# 验证模块是否加载成功
lsmod | grep nvidia_peermem
# 输出示例:
# nvidia_peermem 16384 0
GPUDirect RDMA 的典型数据流如下:
- GPU 应用通过 CUDA 分配显存缓冲区,并调用
cudaHostRegister或使用cuMemAlloc配合 GDR 映射。 - 网卡收到远端数据后,直接通过 PCIe 总线写入 GPU 显存地址。
- GPU 内核函数直接读取该显存区域,无需 CPU 内存中转。
适用条件:GPUDirect RDMA 要求 GPU 与网卡位于同一 PCIe 根复杂(Root Complex)下,或通过支持 PCIe Peer-to-Peer 的交换机连接。跨 NUMA 节点或经过 CPU 桥接的拓扑无法发挥直通优势。
3.3 NVMe over Fabrics:存储协议的网络化延伸
NVMe 协议本身基于 PCIe 点对点传输,天然不支持网络扩展。NVMe over Fabrics(NVMe-oF)将 NVMe 命令封装在 RDMA 或 TCP 传输层上,使远端 NVMe 固态硬盘看起来像本地设备一样。
NVMe-oF 的核心组件包括:
- NVMe 子系统(Subsystem):包含控制器和命名空间(Namespace),是存储服务的提供方。
- NVMe 控制器:处理管理命令和 I/O 命令,支持多队列并行。
- NVMe 队列对(Queue Pair):提交队列(SQ)和完成队列(CQ)通过 RDMA 消息映射到远端。
NVMe-oF 与本地 NVMe 的关键差异在于命令传输路径:
| 对比维度 | 本地 NVMe | NVMe over Fabrics (RDMA) |
|---|---|---|
| 传输层 | PCIe | InfiniBand / RoCE |
| 命令提交 | 写 MMIO 寄存器 | RDMA Send 消息 |
| 数据传输 | PCIe DMA | RDMA Read/Write |
| CPU 参与度 | 极低(硬件自动) | 极低(网卡卸载) |
| 典型延迟 | ~10 μs | ~20-30 μs(RDMA) |
3.4 三层技术叠加:GPU 直连存储的完整路径
当 GPUDirect RDMA 与 NVMe-oF 结合时,GPU 可以直接访问远端 NVMe 固态硬盘中的数据,无需经过本地 CPU 内存。下图展示了这一完整数据通路:
图中绿色实线展示了 GPUDirect RDMA + NVMe-oF 的直通数据路径:GPU 显存通过 PCIe 直连本地 RNIC,RDMA 网络将 NVMe 命令和数据封装传输,远端 RNIC 接收后直接与 NVMe 控制器交互。红色虚线是传统路径,数据需在 CPU 内存停留,增加约 5-10 μs 延迟。
3.5 典型应用场景与配置示例
以深度学习训练中的数据加载为例,传统方式需要 CPU 从存储读取数据再拷贝到 GPU,而 GPUDirect Storage 允许 GPU 直接发起读取请求:
# 使用 nvme-cli 在存储节点创建 NVMe-oF 子系统
nvme nvmeof-create-subsystem -n nqn.2024-01.example:gds -a 10.0.0.2
# 在 GPU 节点发现远端子系统
nvme discover -t rdma -a 10.0.0.2 -s 4420
# 连接远端命名空间
nvme connect -t rdma -n nqn.2024-01.example:gds \
-a 10.0.0.2 -s 4420
# 验证连接
nvme list
连接建立后,GPU 应用通过 CUDA 的 cudaMemcpyAsync 配合 cudaIpcOpenMemHandle 即可直接访问映射到显存地址的存储数据。
3.6 常见误区与调优要点
误区一:认为只要安装了 GPUDirect RDMA 驱动就能自动加速。实际上还需要检查 PCIe 拓扑、BAR 大小、以及 nvidia-peermem 与网卡驱动的兼容性。
误区二:忽略 NUMA 亲和性。GPU 与网卡若不在同一 NUMA 节点,PCIe 跨节点访问会导致带宽下降 30%-50%。
调优检查清单:
- 使用
nvidia-smi topo -m确认 GPU 与网卡的 PCIe 连接类型(PIX 最佳,PXB 次之,CPU 连接最差)。 - 检查
dmesg | grep peermem确认模块加载无错误。 - 使用
ib_write_bw测试网卡到 GPU 显存的真实带宽,而非仅测网卡到内存。 - NVMe-oF 队列深度建议设置为 128-256,过小会限制吞吐,过大会增加延迟。
总结而言,RDMA 提供了网络传输的零拷贝基础,GPUDirect RDMA 将这种能力延伸到 GPU 显存,NVMe-oF 则让存储协议适配 RDMA 传输。三者协同工作时,GPU 应用能够以接近本地 NVMe 的性能访问远端存储,这是 GPU Direct 存储技术的核心价值所在。