nbd-vram:在Linux上使用NVIDIA GPU的显存作为交换空间

Lobsters Hottest 工具

摘要

nbd-vram是一个Linux工具,通过NBD协议和CUDA使用NVIDIA GPU显存作为交换空间,为搭载焊接式内存且无法升级的系统提供额外内存。

<p><a href="https://lobste.rs/s/mdi231/nbd_vram_use_your_nvidia_gpu_s_vram_as_swap">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/06/01 20:35

c0dejedi/nbd-vram

Source: https://github.com/c0dejedi/nbd-vram

nbd-vram

在 Linux 上使用 NVIDIA GPU 的显存作为交换空间。

专为内存焊接在主板、无法升级的笔记本电脑而设计。如果你有一张 RTX 显卡,空着 8GB 显存,而系统正在将数据交换到 SSD,这个工具就能让显存派上用场。

测试环境:RTX 3070 笔记本(GA104M,物理内存 16 GB,显存 8 GB),驱动版本 580.159.03,内核 6.17,Pop!_OS。分配了 7 GB 作为交换空间。最终结果包括 zram 和 SSD 交换共约 46 GB,可寻址内存翻了三倍。溢出顺序:RAM 填满 → VRAM 吸收溢出(快,PCIe)→ zram 压缩剩余部分(CPU)→ 仅在以上全部耗尽时才使用 SSD。

演示


工作原理

一个小型守护进程通过 CUDA 驱动 API 分配显存,然后通过 NBD(网络块设备)协议在 Unix 套接字上将其作为块设备提供服务。内核内置的 nbd 驱动连接到该守护进程,并暴露出 /dev/nbdX。随后它就是一个普通的交换设备。

数据路径:内核交换子系统 → /dev/nbdX → nbd 内核驱动 → Unix 套接字 → nbd-vram 守护进程 → cuMemcpyHtoD/DtoH → GPU 显存。

无需编写或维护内核模块,无需 NVIDIA 内核符号,在升级内核或驱动后无需重新编译任何东西。


为什么不使用 NVIDIA P2P API?

“显而易见”的方法是 nvidia_p2p_get_pages_persistent,它会在 BAR1 中固定显存页,使得 CPU 可以通过 ioremap_wc 直接访问。每一个尝试这条路的现有项目都遇到了同样的障碍:NVIDIA 驱动在消费级 GeForce GPU 上返回 EINVAL。无论持久化还是非持久化变体,无论标志值如何,该 API 都在 RM 层面被限制为 Quadro/数据中心 SKU 专用,与驱动版本无关。

另一种方法——不通过 P2P API 直接对 BAR1 物理地址进行 ioremap_wc——同样无效。GPU 的内部页表仅映射了约 16 MiB 的 BAR1(仅用于显示帧缓冲区)。从其余地址读取返回零。mkswap 看似成功,但随后 swapon 会因为交换头部实际不存在而失败。

NBD 方法绕过了所有这些限制。cuMemcpyHtoDcuMemcpyDtoH 在任何 CUDA GPU 上都能工作,无需任何特殊权限。


要求

  • 支持 CUDA 的 NVIDIA GPU(任意消费级 RTX/GTX 显卡)
  • 带有 libcuda.so.1 的 NVIDIA 驱动(无需 CUDA 工具包)
  • Linux 内核 3.0+(nbd 模块,大多数发行版已内置)
  • nbd-client 软件包
  • gccmake

安装

git clone https://github.com/c0dejedi/nbd-vram
cd nbd-vram
sudo ./install.sh
sudo systemctl start vram-swap-nbd

验证:

swapon --show
# NAME       TYPE      SIZE USED PRIO
# /dev/nbd0  partition   7G   0B 1500

该服务在安装时即被启用,因此每次启动时都会自动运行。


配置

编辑 /etc/systemd/system/vram-swap-nbd.service

Environment=VRAM_SETUP_SIZE_MB=7168    # 要使用的显存量(MB)
Environment=VRAM_SWAP_PRIORITY=1500   # 交换优先级(数值越高,越优先使用)

守护进程首先尝试请求的大小,如果 GPU 内存不足,则以 512 MiB 为步长逐步回退——因此即使显示合成器已占用了部分显存,它也会尽可能多获取。VRAM_SETUP_SIZE_MB 是上限,而非硬性要求。

修改后,运行 sudo systemctl daemon-reload && sudo systemctl restart vram-swap-nbd


快速测试(无需安装)

sudo bash test-nbd.sh

该脚本会分配显存、连接 NBD 设备、执行 1 MiB 写入/回读检查、激活交换,然后打印清理指令。如果已有测试实例在运行,install.sh 会自动执行清理。

快速测试通过后,要对整个分区进行压力测试:

sudo bash test-fill.sh

该脚本会用零填充整个显存分区,验证样本回读,然后在退出时自动恢复交换。


性能

在 RTX 3070 笔记本上通过 test-fill.sh 测量(7 GiB 顺序写入,4M 块):

  • 顺序吞吐量:约 1.3 GB/s
  • 延迟低于 NVMe,因为数据路径通过 PCIe 直达 GPU,而非经过存储设备

对于已使用 zram 的笔记本电脑,将 VRAM 交换设置为更高优先级,使其在溢出时优先于 SSD 吸收数据。


卸载

sudo systemctl disable --now vram-swap-nbd
sudo rm /usr/local/bin/nbd-vram
sudo rm /usr/local/bin/nbd-vram-connect.sh
sudo rm /usr/local/bin/nbd-vram-disconnect.sh
sudo rm /etc/systemd/system/vram-swap-nbd.service
sudo systemctl daemon-reload

许可证

MIT - Sean Lobjoit (c0dejedi)

相似文章

交换表、闪存友好的交换、swap_ops 等

Hacker News Top

本文介绍了 Linux 内核交换子系统的最新改进和未来计划,包括减少每页开销、基于 folio 的辅助函数,以及使交换更适配固态存储的努力。相关内容在 2026 年 Linux 存储、文件系统、内存管理与 BPF 峰会上进行了讨论。