<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>GPUDirect Storage on Hellokitty&#39;s Blog</title>
    <link>https://yangyang233333.github.io/tags/gpudirect-storage/</link>
    <description>Recent content in GPUDirect Storage on Hellokitty&#39;s Blog</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    <lastBuildDate>Fri, 21 Aug 2026 16:25:00 +0800</lastBuildDate>
    <atom:link href="https://yangyang233333.github.io/tags/gpudirect-storage/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>PCIe BAR 深入解析：从设备地址窗口到 DMA 与 GPUDirect Storage</title>
      <link>https://yangyang233333.github.io/posts/pcie-bar-dma-gds/</link>
      <pubDate>Fri, 21 Aug 2026 16:25:00 +0800</pubDate>
      <guid>https://yangyang233333.github.io/posts/pcie-bar-dma-gds/</guid>
      <description>&lt;p&gt;在操作系统驱动、高性能网卡、NVMe SSD 和 GPU 系统中，经常会同时看到 BAR、MMIO、DMA、IOMMU、peer-to-peer DMA、GPUDirect RDMA 和 GPUDirect Storage 等概念。这些名词都与“设备怎样通过 PCIe 交换控制信息和数据”有关，但它们处在不同层次。&lt;/p&gt;
&lt;p&gt;最简洁的理解是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;BAR：让 CPU 能够定位并访问 PCIe 设备中的寄存器或显存窗口
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;DMA：让 PCIe 设备能够主动读取或写入系统内存
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;P2P DMA：让一个 PCIe 设备直接访问另一个 PCIe 设备暴露的地址空间
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;GDS：利用 DMA、GPU 内存映射和驱动协作，让存储数据尽量直接进入 GPU 显存
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;本文从 PCIe 地址空间和事务模型出发，解释 BAR 是如何分配和映射的，驱动为什么通过 BAR 下发命令，DMA 地址为什么不能简单等同于物理地址，以及 GPUDirect Storage 如何把这些机制组合成一条高性能数据路径。&lt;/p&gt;
&lt;h2 id=&#34;一先建立-pcie-系统视图&#34;&gt;一、先建立 PCIe 系统视图&lt;/h2&gt;
&lt;p&gt;一个典型服务器的 PCIe 拓扑如下：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                         CPU
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                          │
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                Memory Controller
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                          │
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                       Host RAM
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                          │
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    Root Complex
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   ┌──────┴──────┐
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   │             │
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              PCIe Switch    PCIe Endpoint
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              ┌────┴────┐         GPU
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              │         │
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           NVMe SSD     NIC
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;CPU 和内存构成主机侧。Root Complex 把 CPU/内存系统连接到 PCIe fabric。NVMe、网卡和 GPU 通常是 Endpoint。PCIe Switch 用于扩展端口和转发事务。&lt;/p&gt;</description>
    </item>
    <item>
      <title>nvidia-fs 源码阅读（三）：文件 I/O、批处理、完成路径与诊断</title>
      <link>https://yangyang233333.github.io/posts/nvidia-fs-source-code-reading-io/</link>
      <pubDate>Fri, 21 Aug 2026 10:47:00 +0800</pubDate>
      <guid>https://yangyang233333.github.io/posts/nvidia-fs-source-code-reading-io/</guid>
      <description>&lt;p&gt;前两篇分别介绍了 &lt;code&gt;nvidia-fs&lt;/code&gt; 的模块结构，以及 GPU virtual address 到 peer DMA address 的映射。本文沿一次 &lt;code&gt;cuFileRead&lt;/code&gt; 对应的内核路径，分析文件 I/O 如何提交、完成和清理，并介绍 batch、稀疏文件、RDMA 与 &lt;code&gt;/proc&lt;/code&gt; 诊断接口。&lt;/p&gt;
&lt;p&gt;阅读版本：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;commit: 328d1d8cce1175c013720985c30e123e9a35242c
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;GDS_VERSION: 2.29.4
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;一io-入口&#34;&gt;一、I/O 入口&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;nvfs_ioctl()&lt;/code&gt; 接收：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NVFS_IOCTL_READ
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NVFS_IOCTL_WRITE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NVFS_IOCTL_BATCH_IO
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;单次读写共用两阶段结构：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nvfs_io_init(op, ioargs)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -&amp;gt; 验证并构造 nvfs_io
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nvfs_io_start_op(nvfsio)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -&amp;gt; 向目标文件提交真正 I/O
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;分成两步的意义在于：参数验证、对象引用和资源分配都应在进入异步 I/O 前完成。一旦请求提交，完成回调可能很快发生，初始化不完整会造成竞态。&lt;/p&gt;
&lt;h2 id=&#34;二nvfs_io_init-做了什么&#34;&gt;二、&lt;code&gt;nvfs_io_init&lt;/code&gt; 做了什么&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;nvfs_io_init()&lt;/code&gt; 是用户参数到内核 I/O 对象的转换层，主要工作包括：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;根据文件描述符取得目标 &lt;code&gt;struct file&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;检查读写权限；&lt;/li&gt;
&lt;li&gt;查找已经注册的 GPU buffer/mgroup；&lt;/li&gt;
&lt;li&gt;验证 GPU buffer offset、文件 offset 和长度；&lt;/li&gt;
&lt;li&gt;建立影子 page 对应的 iov 或迭代器；&lt;/li&gt;
&lt;li&gt;初始化 &lt;code&gt;kiocb&lt;/code&gt;、完成函数和统计字段；&lt;/li&gt;
&lt;li&gt;为同步、异步和特殊文件系统路径设置标志。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;源码还会检查文件系统类型、direct I/O 条件和文件权限。写操作比读操作更复杂，因为它可能涉及文件扩展、页缓存一致性及磁盘空间预分配。&lt;/p&gt;</description>
    </item>
    <item>
      <title>nvidia-fs 源码阅读（二）：GPU 内存注册、影子页与 DMA 映射</title>
      <link>https://yangyang233333.github.io/posts/nvidia-fs-source-code-reading-memory-dma/</link>
      <pubDate>Fri, 21 Aug 2026 10:46:00 +0800</pubDate>
      <guid>https://yangyang233333.github.io/posts/nvidia-fs-source-code-reading-memory-dma/</guid>
      <description>&lt;p&gt;上一篇从 &lt;code&gt;nvfs_init()&lt;/code&gt;、字符设备和 ioctl 看到了 &lt;code&gt;nvidia-fs&lt;/code&gt; 的外部形态。本文进入 GDS direct path 的核心：怎样把用户分配的 GPU virtual address 变成存储设备能够 DMA 的地址，同时又让 Linux 文件 I/O 栈能够携带它。&lt;/p&gt;
&lt;p&gt;阅读版本仍为 NVIDIA &lt;code&gt;gds-nvidia-fs&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;commit: 328d1d8cce1175c013720985c30e123e9a35242c
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;GDS_VERSION: 2.29.4
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;一问题本质&#34;&gt;一、问题本质&lt;/h2&gt;
&lt;p&gt;普通块 I/O 最终围绕 &lt;code&gt;bio_vec&lt;/code&gt;、&lt;code&gt;struct page&lt;/code&gt;、scatterlist 和 DMA mapping 展开。但 &lt;code&gt;cudaMalloc&lt;/code&gt; 得到的是 GPU 虚拟地址，对 Linux 页缓存和块层来说，它并不是普通 CPU 内存页。&lt;/p&gt;
&lt;p&gt;驱动需要解决三次“翻译”：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;GPU virtual address
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -&amp;gt; NVIDIA P2P page table 中的 GPU physical pages
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -&amp;gt; Linux I/O 栈可携带的影子 struct page
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -&amp;gt; 某个存储 PCIe 设备可使用的 DMA address
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;三个地址空间不能混为一谈：&lt;/p&gt;</description>
    </item>
    <item>
      <title>nvidia-fs 源码阅读（一）：模块初始化、设备接口与整体架构</title>
      <link>https://yangyang233333.github.io/posts/nvidia-fs-source-code-reading-architecture/</link>
      <pubDate>Fri, 21 Aug 2026 10:45:00 +0800</pubDate>
      <guid>https://yangyang233333.github.io/posts/nvidia-fs-source-code-reading-architecture/</guid>
      <description>&lt;p&gt;&lt;code&gt;nvidia-fs&lt;/code&gt; 是 NVIDIA GPUDirect Storage（GDS）的 Linux 内核模块。它不是一种文件系统，而是连接 &lt;code&gt;libcufile&lt;/code&gt;、NVIDIA GPU 驱动、Linux 文件 I/O 和支持 GPUDirect 的存储驱动的一层内核协调组件。&lt;/p&gt;
&lt;p&gt;这组文章阅读 NVIDIA 官方 &lt;code&gt;gds-nvidia-fs&lt;/code&gt; 仓库，采用的版本为：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;commit: 328d1d8cce1175c013720985c30e123e9a35242c
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;GDS_VERSION: 2.29.4
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;commit date: 2026-06-01
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;系列分为三篇：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;模块初始化、设备接口与整体架构；&lt;/li&gt;
&lt;li&gt;GPU 内存注册、页表与 DMA 映射；&lt;/li&gt;
&lt;li&gt;文件 I/O、批量请求、完成路径与可观测性。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;本文先回答一个问题：加载 &lt;code&gt;nvidia_fs.ko&lt;/code&gt; 后，内核里究竟多了什么？&lt;/p&gt;
&lt;h2 id=&#34;一源码目录&#34;&gt;一、源码目录&lt;/h2&gt;
&lt;p&gt;核心代码都位于 &lt;code&gt;src/&lt;/code&gt;：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;文件&lt;/th&gt;
					&lt;th&gt;职责&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;nvfs-core.c/.h&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;字符设备、ioctl、GPU 内存注册和文件 I/O 主流程&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;nvfs-mod.c&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;与 NVMe、RDMA 等外部模块动态注册 DMA 回调&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;nvfs-mmap.c/.h&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;GPU 页对应的影子 &lt;code&gt;struct page&lt;/code&gt; 和 mmap 管理&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;nvfs-dma.c/.h&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;block request 到 GPU DMA 地址的映射&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;nvfs-batch.c/.h&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;批量 I/O 提交与完成&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;nvfs-rdma.c/.h&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;RDMA 注册信息管理&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;nvfs-pci.c/.h&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;GPU 与存储设备的 PCIe 拓扑、距离和亲和性&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;nvfs-proc.c&lt;/code&gt;、&lt;code&gt;nvfs-stat.c&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/proc&lt;/code&gt; 配置、统计和诊断接口&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;nvfs-kernel-interface.c&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;不同 Linux 内核版本的兼容封装&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;主线集中在 &lt;code&gt;nvfs-core.c&lt;/code&gt;，但真正的数据直达能力是多个文件共同完成的。&lt;/p&gt;</description>
    </item>
    <item>
      <title>GDS、GIDS 与 uGDS 有什么区别：从数据直达、GPU 发起到用户态 NVMe</title>
      <link>https://yangyang233333.github.io/posts/gds-gids-ugds-comparison/</link>
      <pubDate>Thu, 20 Aug 2026 14:05:00 +0800</pubDate>
      <guid>https://yangyang233333.github.io/posts/gds-gids-ugds-comparison/</guid>
      <description>&lt;p&gt;GDS、GIDS 和 uGDS 的名字非常接近，也都在讨论 GPU 与存储之间的数据通路，因此很容易被理解成同一项技术的三个版本。&lt;/p&gt;
&lt;p&gt;实际上，它们解决的是三个不同层面的问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GDS&lt;/strong&gt; 关注数据路径：怎样让存储数据不经 CPU 内存中转，直接进入 GPU 显存；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GIDS&lt;/strong&gt; 关注控制路径：怎样让 GPU Kernel 自己决定并发起存储请求，减少 GPU 与 CPU 往返；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;uGDS&lt;/strong&gt; 关注软件栈：怎样让 CPU 在用户态直接管理 NVMe 队列，绕过内核 NVMe 驱动与文件系统。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以先用一句话概括：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;GDS 是“数据直达 GPU”，GIDS 是“GPU 主动要数据”，uGDS 是“用户态 CPU 直接驱动 NVMe 把数据送到 GPU”。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;本文从请求由谁发起、数据经过哪里、NVMe 命令由谁构造、是否保留文件系统语义等维度，分析三者的区别与联系。更深入的原理可以继续阅读本系列的三篇文章：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://yangyang233333.github.io/posts/nvidia-gpudirect-storage-gds/&#34;&gt;NVIDIA GPUDirect Storage（GDS）详解：让存储数据绕过 CPU 直达 GPU&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://yangyang233333.github.io/posts/nvidia-gpu-initiated-data-storage-gids/&#34;&gt;NVIDIA GPU-Initiated Data Storage（GIDS）详解：让 GPU Kernel 主动访问存储&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://yangyang233333.github.io/posts/ugds-userspace-gpu-direct-storage/&#34;&gt;uGDS 原理解析：在用户态打通 NVMe SSD 与 GPU 显存&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;一先区分数据路径与控制路径&#34;&gt;一、先区分数据路径与控制路径&lt;/h2&gt;
&lt;p&gt;理解这三项技术的关键，是不要把“数据经过哪里”和“谁发起 I/O”混为一谈。&lt;/p&gt;
&lt;h3 id=&#34;数据路径&#34;&gt;数据路径&lt;/h3&gt;
&lt;p&gt;数据路径描述有效载荷如何移动。例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;传统路径：SSD → CPU 内存 → GPU 显存
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;直接路径：SSD ──────────→ GPU 显存
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;GDS、GIDS 和 uGDS 都希望建立 SSD 与 GPU 显存之间的 DMA 路径，减少 CPU bounce buffer。但“数据不经过 CPU 内存”并不代表“CPU 没有参与”。&lt;/p&gt;</description>
    </item>
    <item>
      <title>NVIDIA GPUDirect Storage（GDS）详解：让存储数据绕过 CPU 直达 GPU</title>
      <link>https://yangyang233333.github.io/posts/nvidia-gpudirect-storage-gds/</link>
      <pubDate>Wed, 19 Aug 2026 14:00:00 +0800</pubDate>
      <guid>https://yangyang233333.github.io/posts/nvidia-gpudirect-storage-gds/</guid>
      <description>&lt;p&gt;在 AI 训练、科学计算和数据分析系统中，GPU 的算力越来越强，但数据从存储设备进入 GPU 的路径却可能成为瓶颈。传统 I/O 通常要先把数据读入 CPU 内存，再复制到 GPU 显存，不仅增加内存带宽消耗，还让 CPU 承担大量数据搬运工作。&lt;/p&gt;
&lt;p&gt;NVIDIA GPUDirect Storage，简称 &lt;strong&gt;GDS&lt;/strong&gt;，解决的正是这个问题：它在存储设备与 GPU 显存之间建立更直接的数据路径，使应用能够通过 &lt;code&gt;cuFile&lt;/code&gt; API 将文件数据读入 GPU 缓冲区，减少 CPU bounce buffer 和不必要的数据复制。&lt;/p&gt;
&lt;p&gt;本文介绍 GDS 的工作原理、软件栈、典型使用方式、适用场景以及它与 GPU-Initiated Data Storage（GIDS）的关系。&lt;/p&gt;
&lt;h2 id=&#34;一传统-gpu-io-为什么效率不高&#34;&gt;一、传统 GPU I/O 为什么效率不高&lt;/h2&gt;
&lt;p&gt;传统文件读取到 GPU 的路径大致如下：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NVMe / 文件系统
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       │
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       ▼
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;CPU 内存缓冲区
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       │ cudaMemcpy
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       ▼
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;GPU 显存
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;应用通常先调用 &lt;code&gt;read&lt;/code&gt;、&lt;code&gt;pread&lt;/code&gt; 或异步 I/O 接口，把文件内容读入主机内存，然后再调用 CUDA memcpy 将数据复制到 GPU。&lt;/p&gt;
&lt;p&gt;这条路径存在几个问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;同一份数据先经过 CPU 内存，再进入 GPU 显存；&lt;/li&gt;
&lt;li&gt;存储流量和 GPU 传输流量竞争 CPU 内存带宽；&lt;/li&gt;
&lt;li&gt;CPU 需要提交、管理和完成数据搬运；&lt;/li&gt;
&lt;li&gt;大规模 GPU 系统中，CPU 和内存通道容易成为共享瓶颈；&lt;/li&gt;
&lt;li&gt;应用需要维护主机端 staging buffer，并处理双重缓冲。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当 GPU 计算越来越快、单机挂载更多 NVMe 或更高速的并行文件系统后，这些额外开销会更加明显。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
