大数跨境
0
0

NVIDIA GPUDirect 技术详解:RDMA 与 Storage

NVIDIA GPUDirect 技术详解:RDMA 与 Storage AI 原力注入
2026-01-16
12
导读:在 AI 场景中,数据规模持续增长,数据传输逐渐成为性能瓶颈。传统架构依赖 CPU 中转 GPU 与网卡、存储的数据,增加延迟并占用资源。英伟达提出的 GPUDirect 技术通过绕过 CPU,实现

 

NVIDIA GPUDirect 技术详解:RDMA 与 Storage

1. 引言

在现代高性能计算 (HPC) 和人工智能 (AI) 领域,随着数据量的爆炸式增长和模型复杂度的提升,数据传输的效率成为了系统性能的关键瓶颈。传统的计算机架构中,GPU 与其他设备(如网卡、存储设备)之间的数据交互往往需要 CPU 作为中转站,这不仅增加了延迟,还占用了宝贵的 CPU 资源。

为了解决这一问题,NVIDIA 推出了 GPUDirect 系列技术。这是一组旨在加速 GPU 与其他设备(如网络接口卡 NIC、存储设备、其他 GPU)之间数据通信的技术集合。本文将重点介绍其中两个关键技术:GPUDirect RDMA 和 GPUDirect Storage (GDS)

2. GPUDirect RDMA 技术

官方文档参考:GPUDirect RDMA Documentation

GPUDirect RDMA (Remote Direct Memory Access) 是一项允许第三方 PCIe 设备(如网络接口卡 NIC、存储适配器等)直接访问 NVIDIA GPU 显存的技术。这项技术最早在 Kepler 架构 GPU 和 CUDA 5.0 中引入,旨在消除 GPU 与第三方设备通信时 CPU 的介入和不必要的系统内存拷贝。

整体架构:

high level view

2.1 技术背景与痛点

在未启用 GPUDirect RDMA 的传统架构中,当 GPU 需要通过网络发送数据时,数据流必须经历“GPU 显存 -> 系统内存 (CPU 参与) -> 网卡”的路径:

  1. 1. 数据拷贝:数据从源 GPU 显存拷贝到源主机的系统内存 (CPU 内存)。
  2. 2. 网络传输:CPU 参与控制,网卡 (NIC) 从系统内存读取数据并通过网络发送。
  3. 3. 接收与拷贝:目标主机网卡将数据写入系统内存,再由 CPU 拷贝到目标 GPU 显存。

这带来了显著的性能瓶颈:

  • • 高延迟:数据在 PCIe 总线上往返,且需要 CPU 处理中断和上下文切换。
  • • 带宽瓶颈:数据流经系统内存,受限于 CPU 内存带宽。
  • • CPU 负载:CPU 必须参与数据的搬运(Memory Copy)和缓冲区管理,无法专注于计算任务。

2.2 工作原理详解

GPUDirect RDMA 利用了标准 PCIe 总线的功能,使第三方设备能够通过 PCI BAR (Base Address Register) 直接对 GPU 显存进行读写操作。

2.2.1 核心机制

当两个 PCIe 设备(例如 GPU 和 NIC)共享同一个上游 Root Complex 时,它们可以通过物理地址直接通信。

  • • PCI BARs 映射:GPU 将其显存的一定区域通过 BARs 暴露在物理地址空间中。
  • • P2P Direct Access:NIC 可以像访问系统内存一样,直接向这些 GPU BAR 地址发起 PCIe Read/Write 事务。
host view

2.2.2 驱动层交互 (Kernel & Userspace)

GPUDirect RDMA 的实现依赖于 NVIDIA Kernel Driver 和用户态 CUDA 库 (Userspace CUDA Library) 的协同工作:

  1. 1. 地址区分:用户态 CUDA 库提供 API 帮助通信库(如 MPI, NCCL)区分指针是指向 CPU 内存还是 GPU 显存。
  2. 2. Pinning GPU Memory (页面锁定)
    • • 对于 CPU 内存,Linux 内核使用 get_user_pages() 进行 Pinning。
    • • 对于 GPU 显存,NVIDIA Kernel Driver 提供了专用的内核 API 来锁定 GPU 页面,并将其物理地址列表返回给 NIC 驱动。
    • • NIC 驱动使用这些物理地址编程 DMA 引擎,从而建立直接的数据传输通道。

2.3 性能优势

GPUDirect RDMA 通过在 GPU 和第三方设备之间建立直接的数据传输通道,消除了不必要的系统内存拷贝和 CPU 介入,从而实现了极致的通信性能。

  • • Zero-Copy (零拷贝):完全消除了 GPU 显存到系统内存的缓冲拷贝。
  • • 降低延迟:数据直接在设备间传输,端到端延迟通常可降低至原来的 1/10 甚至更低。
  • • 完全卸载:CPU 仅需负责建立连接和控制流,数据路径完全旁路 CPU。

2.4 开发者视角:代码与 API

虽然上层应用通常使用 CUDA-aware MPI 或 NCCL 来隐式使用 GPUDirect RDMA,但在底层驱动开发中,涉及以下关键步骤:


   
   
   
    
   
   
   // 伪代码示例:展示 NIC 驱动如何注册 GPU 显存以进行 RDMA
// 实际上,这通常由 InfiniBand Verbs (libibverbs) 库在用户态封装


// 1. 用户态分配 GPU 内存

void
* d_buffer;
cudaMalloc(&d_buffer, size);

// 2. 注册内存区域 (Memory Region Registration)

// 此时,libibverbs 会检测指针类型。如果是 GPU 指针,

// 它会调用 NVIDIA 内核驱动提供的 nvidia_p2p_get_pages 等接口

// 来获取 GPU 页面的物理地址,并将其写入 NIC 的页表 (MTT/MKEY)。


struct ibv_mr *mr = ibv_reg_mr(pd, d_buffer, size,
                               IBV_ACCESS_LOCAL_WRITE |
                               IBV_ACCESS_REMOTE_WRITE |
                               IBV_ACCESS_REMOTE_READ);

if
 (!mr) {
    // 注册失败,可能因硬件不支持或未加载 nvidia-peermem 模块

    fprintf
(stderr, "GPUDirect RDMA registration failed\n");
}

// 3. 执行 RDMA 操作 (Send/Recv/Write/Read)

// NIC 硬件 DMA 引擎直接通过 PCIe 总线访问 d_buffer 的物理地址

ibv_post_send(qp, &wr, &bad_wr);

注意:要启用此功能,系统通常需要加载 nvidia-peermem (或旧版的 nv_peer_mem) 内核模块,该模块充当 NVIDIA 驱动与 InfiniBand 核心驱动之间的桥梁。


3. GPUDirect Storage (GDS) 技术

官方文档参考:GPUDirect Storage Documentation

随着 AI、HPC 以及数据分析领域的数据集规模持续增长,数据加载所消耗的时间开始对应用整体性能产生显著影响。高速 GPU 往往受限于缓慢的 I/O,尤其是在将数据从存储系统加载到 GPU 显存以进行计算处理的过程中。

GPUDirect Storage (GDS) 旨在建立一条在本地或远程存储(如 NVMe 或 NVMe over Fabrics, NVMe-oF)与 GPU 内存之间的直接数据通路。该技术避免了通过 CPU 内存中的中转缓冲区(Bounce Buffer)进行额外的数据拷贝,使位于网卡或存储设备附近的直接内存访问(DMA)引擎能够沿着一条直达路径将数据直接传入或传出 GPU 内存,全程无需给 CPU 带来额外负担。

整体架构:

high level view

3.1 技术背景与痛点

在传统的存储 I/O 路径中,将数据从磁盘读取到 GPU 显存是一个多阶段、低效率的过程:

  1. 1. 内核态缓冲:存储设备(如 NVMe SSD)通过 DMA 将数据写入操作系统内核空间的 Page Cache。
  2. 2. 用户态拷贝:CPU 将数据从内核空间拷贝到用户空间的应用程序缓冲区 (CPU 内存)。
  3. 3. H2D 拷贝:CPU 再次将数据从用户空间缓冲区拷贝到 GPU 显存 (Host-to-Device)。

这种被称为“Bounce Buffer”效应的机制存在三大问题:

  • • CPU 瓶颈:CPU 必须参与每一次内存拷贝,随着 NVMe 速度提升,CPU 逐渐成为瓶颈。
  • • 延迟增加:多次内存拷贝和上下文切换显著增加了端到端延迟。
  • • PCIe 带宽浪费:数据在 PCIe 总线上来回传输(SSD -> CPU -> GPU),实际上占用了两倍的 PCIe 带宽。

3.2 工作原理详解

GPUDirect Storage 引入了全新的文件系统架构,允许存储设备直接对 GPU 显存进行 DMA 操作。

3.2.1 核心组件:cuFile API 与 libcufile

GDS 提供了一套名为 cuFile 的用户态 API,它类似于 POSIX 文件操作 API(如 read/write),但专为 GPU 显存设计。

  • • libcufile:这是 GDS 的核心库,负责拦截 cuFile I/O 请求,并智能选择最佳传输路径。
  • • nvidia-fs.ko:这是一个内核模块,负责处理文件系统元数据、页面锁定以及 DMA 映射。它与标准文件系统(如 ext4, xfs)协同工作,但绕过了 Page Cache。

3.2.2 DMA 路径选择

当应用程序调用 cuFileRead 时:

  1. 1. Pinningnvidia-fs 锁定目标 GPU 显存页面。
  2. 2. DMA 映射:将 GPU 物理地址提供给 NVMe 驱动程序。
  3. 3. Direct Transfer:NVMe 控制器启动 DMA,通过 PCIe P2P (Peer-to-Peer) 机制直接将数据写入 GPU 显存。

如果硬件或系统配置不支持 P2P(例如设备不在同一个 PCIe Root Complex 下),GDS 会自动回退到传统的系统内存缓冲模式,但仍会尝试优化路径。

3.3 核心优势

GDS 通过构建存储到 GPU 的直通高速公路,打破了传统 I/O 的带宽和延迟瓶颈,并彻底解放了 CPU 算力。

  • • 带宽倍增:直接利用 PCIe P2P 特性,吞吐量可接近存储设备或 PCIe 总线的物理极限。根据官方数据,GDS 带宽可达传统 I/O 的 2-8 倍。
  • • 延迟最小化:消除了中间的内存拷贝步骤,I/O 延迟显著降低。
  • • CPU 卸载 (CPU Offloading):CPU 仅需处理控制流,不再参与繁重的数据搬运,从而释放 CPU 算力用于预处理或其他逻辑。

3.4 性能对比数据参考

下表从数据路径、资源消耗等维度,直观展示了 GDS 相比传统 I/O 模式的代际性能提升。

指标
传统 IO (Buffered IO)
传统 Direct IO (O_DIRECT)
GPUDirect Storage (GDS)
数据路径
Storage -> Kernel Buffer -> User Buffer -> GPU
Storage -> User Buffer -> GPU
Storage -> GPU
内存拷贝次数
2 次 (Kernel->User, User->GPU)
1 次 (User->GPU)
0 次
CPU 参与度
高 (数据搬运 & 控制)
中 (单次搬运 & 控制)
低 (仅控制)
带宽利用率
受限于 CPU 内存带宽和拷贝速度
受限于 CPU 内存带宽和拷贝速度
接近 PCIe/NVMe 极限
延迟

3.5 代码示例 (cuFile API)

使用 GDS 需要包含 <cufile.h> 头文件,并链接 libcufile.so。以下是一个简化的 GDS 读取流程:


   
   
   
    
   
   
   #include <fcntl.h>
#include <unistd.h>

#include <cuda_runtime.h>

#include "cufile.h"


int main() {
    const
 char* filename = "test_data.bin";
    size_t
 size = 1024 * 1024 * 1024; // 1GB
    void
* d_buffer;

    // 1. 初始化 cuFile 驱动

    // 这会加载必要的 GDS 驱动并检查硬件兼容性

    cuFileDriverOpen
();

    // 2. 分配 GPU 显存

    cudaMalloc
(&d_buffer, size);

    // 3. 打开文件

    // 必须使用 O_DIRECT 标志,这是 GDS 的前提条件,以绕过操作系统 Page Cache

    int
 fd = open(filename, O_RDONLY | O_DIRECT);

    // 4. 注册 cuFile 句柄

    // 这一步将文件描述符与 GDS 上下文绑定

    CUfileDescr_t cf_descr;
    memset
(&cf_descr, 0, sizeof(CUfileDescr_t));
    cf_descr.handle.fd = fd;
    cf_descr.type = CU_FILE_HANDLE_TYPE_OPAQUE_FD;

    CUfileHandle_t cf_handle;
    cuFileHandleRegister
(&cf_handle, &cf_descr);

    // 5. 直接读取数据到 GPU 显存 (GDS Read)

    // 此时数据直接从 NVMe 流向 GPU,不经过 CPU 内存

    // 参数:handle, devPtr, size, file_offset, devPtr_offset

    cuFileRead
(cf_handle, d_buffer, size, 0, 0);

    // ... 进行 GPU 计算 ...


    // 6. 清理资源

    cuFileHandleDeregister
(cf_handle);
    close
(fd);
    cudaFree
(d_buffer);
    cuFileDriverClose
();

    return
 0;
}

4. GPUDirect 生态系统支持

GPUDirect 技术(涵盖 RDMA 和 Storage)已经建立了庞大的软硬件生态系统,从底层的网卡和存储设备,到中间件通信库,再到上层的 AI 框架,均有广泛支持。

4.1 GPUDirect RDMA 生态

GPUDirect RDMA 是构建高性能分布式 GPU 集群的基石,主要支持来自于高性能网络厂商和并行计算库。

  • • 网络硬件 (NICs)
    • • NVIDIA Mellanox ConnectX 系列:ConnectX-5/6/7 等 InfiniBand 和 Ethernet 网卡对 GPUDirect RDMA 有着最完善的原生支持。
    • • AWS EFA (Elastic Fabric Adapter):在 AWS 云环境中支持 GPUDirect RDMA,加速云上 HPC 和 AI 负载。
    • • Broadcom / Chelsio:部分高性能网卡也提供驱动级支持。
  • • 通信库 (Communication Libraries)
    • • NVIDIA NCCL:深度学习事实上的标准通信库,利用 GPUDirect RDMA 实现高效的 AllReduce, AllGather 等集合通信操作。
    • • MPI (Message Passing Interface):主流 MPI 实现(如 OpenMPIMVAPICH2)均支持 CUDA-aware MPI,底层自动调用 GPUDirect RDMA。
    • • NVSHMEM:提供基于 OpenSHMEM 标准的单边通信 (One-Sided Communication) 能力,利用 RDMA 实现 GPU 全局地址空间访问。
    • • UCX (Unified Communication X):作为底层通信框架,为 MPI 和 PGAS 语言提供 GPUDirect RDMA 加速支持。

4.2 GPUDirect Storage (GDS) 生态

GDS 聚焦于存储 I/O 加速,得到了存储业界和文件系统厂商的广泛集成。

4.2.1 支持的文件系统 (File Systems)

  • • 本地文件系统
    • • ext4:Linux 标准文件系统,GDS 驱动 (nvidia-fs) 对其有原生支持(需在 ordered mode 下)。
    • • xfs:高性能日志文件系统,同样被 nvidia-fs 原生支持。
  • • 并行/分布式文件系统
    • • DDN EXAScaler (Lustre):基于 Lustre 的高性能文件系统,广泛用于超算中心。
    • • IBM Spectrum Scale (GPFS):企业级并行文件系统,支持 GDS 以加速 AI 工作负载。
    • • WekaFS:专为 AI 和 HPC 设计的高性能文件系统,提供极低的延迟。
    • • VAST Data NFS:通过 NFS over RDMA 支持 GDS。
    • • BeeGFS:轻量级并行文件系统,支持通过 RDMA 直接写入 GPU。
    • • Amazon FSx for Lustre:AWS 上的托管 Lustre 服务,支持在 EC2 实例上使用 GDS。

4.2.2 存储解决方案合作伙伴

多家存储硬件厂商已在其产品中集成了对 GDS 的支持:

  • • NetApp ONTAP:提供基于 AI 优化的全闪存存储阵列。
  • • Dell EMC Isilon / PowerScale:横向扩展 NAS 存储。
  • • Pure Storage FlashBlade:专为非结构化数据设计的高性能全闪存。
  • • Hitachi Vantara / Micron / Excelero 等。

4.3 上层 AI 框架集成

为了让开发者无感使用底层加速技术,主流 AI 框架和数据加载库都进行了深度集成:

  • • NVIDIA DALI (Data Loading Library):深度学习数据加载库,原生支持 GDS,可显著加速图像/视频数据的预处理流水线,解决 GPU 饥饿问题。
  • • PyTorch:通过插件或与 DALI 集成支持 GDS;其分布式训练模块(DistributedDataParallel)底层依赖 NCCL 使用 GPUDirect RDMA。
  • • RAPIDS cuDF:GPU 数据帧库,支持使用 GDS 加速大规模 Parquet/CSV/ORC 数据的读取(实验性)。
  • • TensorFlow:通过集成 NCCL 和相关 I/O 插件获得加速能力。

注意:具体的支持版本和配置要求(如内核版本、OFED 版本)请务必参考各厂商的官方文档以及 NVIDIA GDS Support Matrix。


5. 总结

GPUDirect 系列技术(RDMA 与 Storage)是 NVIDIA 针对现代高性能计算和 AI 负载中“数据搬运瓶颈”提出的核心解决方案。它们共同的目标是消除 CPU 在数据路径中的介入,实现设备间的直接内存访问 (DMA)

  1. 1. 核心价值
    • • GPUDirect RDMA:打破了计算节点间的通信壁垒。它允许 GPU 直接通过网卡与其他节点的 GPU 交换数据,消除了 PCIe 总线上的冗余拷贝。这对于**分布式训练(Model/Data Parallelism)**至关重要,能够显著提升多机多卡环境下的扩展效率。
    • • GPUDirect Storage (GDS):打破了计算与存储间的 I/O 壁垒。它允许 GPU 直接从 NVMe 存储设备读取数据,绕过 CPU 内存和 Page Cache。这对于大数据集训练、推理和实时数据分析至关重要,解决了 GPU 因等待数据而空转的问题(GPU Starvation)。
  2. 2. 协同效应
    在构建如 NVIDIA DGX SuperPOD 这样的大规模 AI 集群时,这两项技术通常是互补且共存的。GDS 负责将海量数据高速“喂”入 GPU,而 GPUDirect RDMA 负责在 GPU 集群内部高速同步梯度和模型参数。
  3. 3. 架构演进
    GPUDirect 技术的普及标志着计算架构从“以 CPU 为中心”向“以数据为中心”的转变。在这种新架构下,CPU 退居为控制平面的指挥者,而繁重的数据流动则在 GPU、网卡和存储设备之间通过 PCIe/NVLink 高速通道直接完成,从而释放了系统的全部潜能。

 


【声明】内容源于网络
0
0
AI 原力注入
微软 CEO 萨提亚曾说:“所有产品都值得用 AI 重做一遍。” 我们正处在一场深刻变革中,唯有用 AI 赋能自身,才能拥抱未来。原力注入从云原生迈向 AI 新时代,期待在这个伟大时代中持续成长、不断突破。
内容 515
粉丝 0
AI 原力注入 微软 CEO 萨提亚曾说:“所有产品都值得用 AI 重做一遍。” 我们正处在一场深刻变革中,唯有用 AI 赋能自身,才能拥抱未来。原力注入从云原生迈向 AI 新时代,期待在这个伟大时代中持续成长、不断突破。
总阅读225
粉丝0
内容515