惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LangChain Blog
Recent Announcements
Recent Announcements
GbyAI
GbyAI
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Microsoft Azure Blog
Microsoft Azure Blog
N
Netflix TechBlog - Medium
人人都是产品经理
人人都是产品经理
MongoDB | Blog
MongoDB | Blog
D
DataBreaches.Net
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
WordPress大学
WordPress大学
U
Unit 42
腾讯CDC
D
Docker
The GitHub Blog
The GitHub Blog
阮一峰的网络日志
阮一峰的网络日志
Vercel News
Vercel News
I
InfoQ
Jina AI
Jina AI
爱范儿
爱范儿
宝玉的分享
宝玉的分享
博客园 - Franky
G
Google Developers Blog
P
Proofpoint News Feed

陈少文的网站

巨变与机遇的未来十年 Kubernetes 平台管理软件压力测试方案 使用镜像部署 Hexo 静态页面 终于等到你 - GitHub 镜像仓库服务(ghcr.io) 一起来学 Go --(6)Interface 一起来学 Go --(5)Goroutine 和 Channel 什么是函数式编程 如何在 Kubernetes 集群集成 Kata 柯里化与偏函数 使用 PyGithub 自动创建 Label 软件产品是团队能力的输出 Helm 2 、Helm 3 比较 IoT 变现 Kubernetes 中的 DNS 服务 国内的 Helm 镜像源 Harbor 使用自签证书支持 Https 访问 DevOps 工具链之 Prow 如何使用 kfctl 安装 Kubeflow VS Code 无法下载 Go 插件的工具包 工程师更应具有服务精神 你不知道的 Docker 使用技巧 使用 Docker 运行 Tensorflow 论中国 什么是左移 如何清空 Git 仓库全部历史记录 一禅小和尚 有风吹过厨房 时间的玫瑰 如何在 CentOS 安装 GPU 驱动 开发 Tips(19)
GPU 主机如何开启 GDS
微信公众号 · 2024-09-11 · via 陈少文的网站

1. 什么是 GDS(GPUDirectStorage)

GDS 允许 RDMA 网卡直接访问 GPU 内存,有助于增加 GPU 应用读写文件的 IO 带宽,减少 IO 时延,并降低其 CPU 负载。

客户端在开启 GDS 特性后,文件将以 O_DIRECT 方式打开,客户端不会再缓存文件数据。应用层读写文件时,客户端通过 nvidia-fs.ko 将应用层的 GPU 内存地址转换成 DMA 地址,并将其发送到服务端,由服务端 RDMA 网卡负责对客户端的 DMA 地址读取或填充。

2. 使用要求

2.1 系统要求

  • OS

Ubuntu 20.04,Ubuntu 22.04,Ubuntu 24.04,RHEL 8, RHEL 9

  • CUDA Toolkit

  • GCC

2.2 存储要求

在使用 GDS 时,需要应用层调用 cuFile API 才能正常工作。只有有限的存储系统实现了对 GDS 的支持:

  • NVMe
  • NVMeOF
  • SCSI
  • ScaleFlux CSD
  • NVMesh
  • DDN EXAScaler
  • IBM Spectrum Scale
  • NFS
  • BeeGFS
  • WekaFS

这里有一份 2021 年底的支持列表可以参考: https://developer.nvidia.com/zh-cn/blog/accelerating-io-in-the-modern-data-center-magnum-io-storage-partnerships/

3. 安装 GDS

3.1 安装依赖项

  • 安装 cuda-keyring
1
2
3
4
5
export distro=ubuntu2004
export arch=x86_64
wget https://developer.download.nvidia.com/compute/cuda/repos/$distro/$arch/cuda-keyring_1.1-1_all.deb
sudo dpkg -i cuda-keyring_1.1-1_all.deb
apt-get update
  • 安装 nvidia-fs
1
2
3
apt list --installed | grep nvidia-fs
apt-cache search nvidia-fs
apt-get install nvidia-fs-dkms nvidia-fs
  • 查看当前 Driver 版本
1
2
3
nvidia-smi | grep "Driver Version"

| NVIDIA-SMI 535.129.03             Driver Version: 535.129.03   CUDA Version: 12.2     |
  • 安装 libnvidia-nscq

安装之前需要检查一下是否已经安装,再去寻找与 Driver 版本匹配的版本。

1
2
3
apt list --installed | grep libnvidia_nscq
apt-cache search libnvidia-nscq
apt-get install libnvidia-nscq-535
  • 安装 fabricmanager

安装之前需要检查一下是否已经安装,再去寻找与 Driver 版本匹配的版本。

1
2
3
apt list --installed | grep fabricmanager
apt-cache search fabricmanager
apt-get install nvidia-fabricmanager-535

3.2 安装 GDS

  • 安装 GDS
1
2
3
apt list --installed | grep nvidia-gds
apt-cache search nvidia-gds
apt-get install nvidia-gds-12-2
  • 检查 GDS 状态
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/usr/local/cuda-12.2/gds/tools/gdscheck.py -p

 GDS release version: 1.7.2.10
 nvidia_fs version:  2.22 libcufile version: 2.12
 Platform: x86_64
 ============
 ENVIRONMENT:
 ============
 =====================
 DRIVER CONFIGURATION:
 =====================
 NVMe               : Supported
 NVMeOF             : Unsupported
 SCSI               : Unsupported
 ScaleFlux CSD      : Unsupported
 NVMesh             : Unsupported
 DDN EXAScaler      : Unsupported
 IBM Spectrum Scale : Unsupported
 NFS                : Unsupported
 BeeGFS             : Unsupported
 WekaFS             : Unsupported
 Userspace RDMA     : Unsupported
 --Mellanox PeerDirect : Enabled
 --rdma library        : Not Loaded (libcufile_rdma.so)
 --rdma devices        : Not configured
 --rdma_device_status  : Up: 0 Down: 0
 =====================
 CUFILE CONFIGURATION:
 =====================
 properties.use_compat_mode : true
 properties.force_compat_mode : false
 properties.gds_rdma_write_support : true
 properties.use_poll_mode : false
 properties.poll_mode_max_size_kb : 4
 properties.max_batch_io_size : 128
 properties.max_batch_io_timeout_msecs : 5
 properties.max_direct_io_size_kb : 16384
 properties.max_device_cache_size_kb : 131072
 properties.max_device_pinned_mem_size_kb : 33554432
 properties.posix_pool_slab_size_kb : 4 1024 16384
 properties.posix_pool_slab_count : 128 64 32
 properties.rdma_peer_affinity_policy : RoundRobin
 properties.rdma_dynamic_routing : 0
 fs.generic.posix_unaligned_writes : false
 fs.lustre.posix_gds_min_kb: 0
 fs.beegfs.posix_gds_min_kb: 0
 fs.weka.rdma_write_support: false
 fs.gpfs.gds_write_support: false
 profile.nvtx : false
 profile.cufile_stats : 0
 miscellaneous.api_check_aggressive : false
 execution.max_io_threads : 4
 execution.max_io_queue_depth : 128
 execution.parallel_io : true
 execution.min_io_threshold_size_kb : 8192
 execution.max_request_parallelism : 4
 properties.force_odirect_mode : false
 properties.prefer_iouring : false
 =========
 GPU INFO:
 =========
 GPU index 0 NVIDIA A800-SXM4-80GB bar:1 bar size (MiB):131072 supports GDS,IOMMU State: Disabled
 GPU index 1 NVIDIA A800-SXM4-80GB bar:1 bar size (MiB):131072 supports GDS,IOMMU State: Disabled
 GPU index 2 NVIDIA A800-SXM4-80GB bar:1 bar size (MiB):131072 supports GDS,IOMMU State: Disabled
 GPU index 3 NVIDIA A800-SXM4-80GB bar:1 bar size (MiB):131072 supports GDS,IOMMU State: Disabled
 GPU index 4 NVIDIA A800-SXM4-80GB bar:1 bar size (MiB):131072 supports GDS,IOMMU State: Disabled
 GPU index 5 NVIDIA A800-SXM4-80GB bar:1 bar size (MiB):131072 supports GDS,IOMMU State: Disabled
 GPU index 6 NVIDIA A800-SXM4-80GB bar:1 bar size (MiB):131072 supports GDS,IOMMU State: Disabled
 GPU index 7 NVIDIA A800-SXM4-80GB bar:1 bar size (MiB):131072 supports GDS,IOMMU State: Disabled
 ==============
 PLATFORM INFO:
 ==============
 IOMMU: disabled
 Platform verification succeeded

由于没有额外支持 GDS 的存储系统,仅 NVMe 设备处于支持 GDS 的状态。

4. 测试 GDS

4.1 创建一个 100G 的文件

1
time dd if=/dev/zero of=/data/test/dd.txt bs=40M count=2500

4.2 不同传输模型下的测试

/usr/local/cuda-12.2/gds/tools/gdsio 提供了 8 个不同的测试模式,分别是:

  • 0 - Storage->GPU (GDS)

GPU Direct Storage (GDS): 数据直接从存储传输到 GPU,绕过 CPU。这种模式减少了延迟并增加了吞吐量,特别适合需要 GPU 高速访问数据的场景。

1
2
3
/usr/local/cuda-12.2/gds/tools/gdsio -f /data/test/dd.txt -d 0 -w 4 -s 10G -i 1M -I 0 -x 0

IoType: READ XferType: GPUD Threads: 4 DataSetSize: 10203136/10240000(KiB) IOSize: 1024(KiB) Throughput: 4.443489 GiB/sec,Avg_Latency: 878.805571 usecs ops: 9964 total_time 2.189826 secs
  • 1 - Storage->CPU

存储到 CPU 的传统传输: 数据首先从存储传输到 CPU。这是传统的处理方式,CPU 接收并处理数据,然后再传递给其他组件,比如 GPU。

1
2
3
/usr/local/cuda-12.2/gds/tools/gdsio -f /data/test/dd.txt -d 0 -w 4 -s 10G -i 1M -I 0 -x 1

IoType: READ XferType: CPUONLY Threads: 4 DataSetSize: 10240000/10240000(KiB) IOSize: 1024(KiB) Throughput: 4.414133 GiB/sec,Avg_Latency: 868.366600 usecs ops: 10000 total_time 2.212354 secs
  • 2 - Storage->CPU->GPU

存储到 CPU 再到 GPU: 数据先从存储传输到 CPU,经过处理后再传输到 GPU。这是更常见的流程,适用于需要 CPU 进行数据预处理的场景。

1
2
3
/usr/local/cuda-12.2/gds/tools/gdsio -f /data/test/dd.txt -d 0 -w 4 -s 10G -i 1M -I 0 -x 2

IoType: READ XferType: CPU_GPU Threads: 4 DataSetSize: 10142720/10240000(KiB) IOSize: 1024(KiB) Throughput: 4.312804 GiB/sec,Avg_Latency: 905.410136 usecs ops: 9905 total_time 2.242822 secs
  • 3 - Storage->CPU->GPU_ASYNC

存储到 CPU 再到 GPU 的异步传输: 数据先从存储传输到 CPU,然后异步传输到 GPU。这种模式允许 CPU 在等待数据传输完成的同时执行其他任务,提高了效率。

1
2
3
/usr/local/cuda-12.2/gds/tools/gdsio -f /data/test/dd.txt -d 0 -w 4 -s 10G -i 1M -I 0 -x 3

IoType: READ XferType: CPU_ASYNC_GPU Threads: 4 DataSetSize: 10167296/10240000(KiB) IOSize: 1024(KiB) Throughput: 3.318594 GiB/sec,Avg_Latency: 1176.616969 usecs ops: 9929 total_time 2.921806 secs
  • 4 - Storage->PAGE_CACHE->CPU->GPU

存储->页缓存->CPU->GPU: 数据首先进入操作系统的页缓存,然后传输到 CPU,最后传输到 GPU。页缓存可以加快对常用数据的访问速度,但会增加一步缓存操作。

1
2
3
/usr/local/cuda-12.2/gds/tools/gdsio -f /data/test/dd.txt -d 0 -w 4 -s 10G -i 1M -I 0 -x 4

IoType: READ XferType: CPU_CACHED_GPU Threads: 4 DataSetSize: 10011648/10240000(KiB) IOSize: 1024(KiB) Throughput: 1.770729 GiB/sec,Avg_Latency: 2206.536591 usecs ops: 9777 total_time 5.392046 secs
  • 5 - Storage->GPU_ASYNC

存储到 GPU 的异步传输: 数据直接从存储异步传输到 GPU,允许其他操作在传输过程中继续执行,减少等待时间,提高整体处理效率。

1
2
3
/usr/local/cuda-12.2/gds/tools/gdsio -f /data/test/dd.txt -d 0 -w 4 -s 10G -i 1M -I 0 -x 5

IoType: READ XferType: ASYNC Threads: 4 DataSetSize: 10160128/10240000(KiB) IOSize: 1024(KiB) Throughput: 3.053654 GiB/sec,Avg_Latency: 1272.345376 usecs ops: 9922 total_time 3.173068 secs
  • 6 - Storage->GPU_BATCH

存储到 GPU 的批处理传输: 数据从存储传输到 GPU,但采用批处理的方式进行。适用于需要一次性处理大量数据的情况。

1
2
3
/usr/local/cuda-12.2/gds/tools/gdsio -f /data/test/dd.txt -d 0 -w 4 -s 10G -i 1M -I 0 -x 6

IoType: READ XferType: GPU_BATCH Threads: 1 IoDepth: 4 DataSetSize: 10240000/10240000(KiB) IOSize: 1024(KiB) Throughput: 4.422783 GiB/sec,Avg_Latency: 873.240876 usecs ops: 10001 total_time 2.208027 secs
  • 7 - Storage->GPU_BATCH_STREAM

存储到 GPU 的流式批处理传输: 这是一种批处理和流式处理结合的模式,数据从存储传输到 GPU 时,采用流式处理进行批处理,进一步优化了处理速度和资源利用率。

1
2
3
/usr/local/cuda-12.2/gds/tools/gdsio -f /data/test/dd.txt -d 0 -w 4 -s 10G -i 1M -I 0 -x 7

IoType: READ XferType: GPU_BATCH_STREAM Threads: 1 IoDepth: 4 DataSetSize: 10240000/10240000(KiB) IOSize: 1024(KiB) Throughput: 2.437489 GiB/sec,Avg_Latency: 1600.979502 usecs ops: 10001 total_time 4.006429 secs

4.3 不同模式下的测试结果

模式速度 (GiB/sec)
0 - Storage->GPU (GDS)4.443489 GiB/sec
1 - Storage->CPU4.414133 GiB/sec
2 - Storage->CPU->GPU4.312804 GiB/sec
3 - Storage->CPU->GPU_ASYNC3.318594 GiB/sec
4 - Storage->PAGE_CACHE->CPU->GPU1.770729 GiB/sec
5 - Storage->GPU_ASYNC3.053654 GiB/sec
6 - Storage->GPU_BATCH4.422783 GiB/sec
7 - Storage->GPU_BATCH_STREAM2.437489 GiB/sec
  • Storage->GPU (GDS)\Storage->GPU_BATCH: 速度最高,因为数据直接从存储传输到 GPU,绕过了 CPU
  • Storage->CPU->GPU_ASYNC 和 Storage->GPU_ASYNC: 异步模式下的速度稍低一些,因为异步传输增加了管理开销
  • Storage->PAGE_CACHE->CPU->GPU: 数速度最低,因为数据经过了页缓存,增加了额外的步骤

4.3 验证 GDS 模式下对 CPU 的低使用率

主要对比模式 0 和 2

  • 0 - Storage->GPU (GDS)
1
2
3
/usr/local/cuda-12.2/gds/tools/gdsio -f /data/test/dd.txt -d 0 -w 40 -s 100G -i 1M -I 0 -x 0

IoType: READ XferType: GPUD Threads: 40 DataSetSize: 101975040/102400000(KiB) IOSize: 1024(KiB) Throughput: 6.653494 GiB/sec,Avg_Latency: 5870.442542 usecs ops: 99585 total_time 14.616528 secs
1
2
PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
43261 root      20   0   41.9g 753364 700692 D  18.8   0.1   0:04.69 gdsio
  • 2 - Storage->CPU->GPU
1
2
3
/usr/local/cuda-12.2/gds/tools/gdsio -f /data/test/dd.txt -d 0 -w 40 -s 100G -i 1M -I 0 -x 2

IoType: READ XferType: CPU_GPU Threads: 40 DataSetSize: 101849088/102400000(KiB) IOSize: 1024(KiB) Throughput: 6.649129 GiB/sec,Avg_Latency: 5874.226678 usecs ops: 99462 total_time 14.608058 secs
1
2
PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
47977 root      20   0   36.0g 153276 138644 S  63.7   0.0   0:03.27 gdsio

可以看到在 GDS 模式下,CPU 使用率只有经过 CPU 传输的 30%。

5. 参考