在显存上使用交换空间
在极少数情况下,如果您只有极少的 RAM 但有大量的显存,您可以将后者用作交换空间。
MTD 内核子系统
潜在优势
具有 GDDRX SDRAM 或 DDR SDRAM 的显卡可以通过使用内核的 MTD 子系统用作交换空间。拥有 256 MB 或更大专用显存并且系统内存 (DDRX SDRAM) 有限的系统可能会从这种类型的设置中获益最多。
- 这不适用于闭源驱动程序。
- 除非您的图形驱动程序可以设置为比检测到的内存使用更少的内存,否则当您尝试使用同一部分 RAM 来存储纹理作为交换空间时,Xorg 可能会崩溃。使用允许您覆盖显存的视频驱动程序应该可以提高稳定性。
准备工作
您必须加载模块,指定与显卡上的 RAM 相对应的 PCI 地址范围。
要查找可用的内存范围,请运行以下命令并查找 VGA 兼容控制器部分(请参阅下面的示例)。
$ lspci -vvv
01:00.0 VGA compatible controller: NVIDIA Corporation GK104 [GeForce GTX 670] (rev a1) (prog-if 00 [VGA controller]) Subsystem: ASUSTeK Computer Inc. Device 8405 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin A routed to IRQ 57 Region 0: Memory at f5000000 (32-bit, non-prefetchable) [size=16M] Region 1: Memory at e8000000 (64-bit, prefetchable) [size=128M] Region 3: Memory at f0000000 (64-bit, prefetchable) [size=32M] Region 5: I/O ports at e000 [size=128] [virtual] Expansion ROM at f6000000 [disabled] [size=512K] Capabilities: <access denied> Kernel driver in use: nvidia Kernel modules: nouveau, nvidia
最具潜在优势的是可预取的、64 位的且尺寸最大的区域。
显卡需要一部分内存才能运行,因此需要进行一些计算。偏移量很容易计算,因为它是 2 的幂。显卡应使用地址范围的开头作为纹理等的帧缓冲区。但是,如果受到限制,或者如本文开头所述,如果两个程序尝试写入相同的扇区,则很可能发生稳定性问题。
例如:对于总共 256 MB 的显存,公式为 2^28(2 的 28 次方)。大约 64 MB 可以留给显存,因此显存交换用途的起始范围将使用公式 2^26 计算。
使用上面的数字,您可以取差值并确定用作交换内存的合理范围。为正常功能留下 2^24 (32M)(更少也可以正常工作)
配置
配置 phram 模块(3.x 内核使用 slram 模块)
/etc/modprobe.d/modprobe.conf
options phram phram=VRAM,0xStartRange,0xUsedAmount
在启动时加载模块
/etc/modules-load.d/vramswap.conf
phram mtdblock
创建一个 systemd 服务
/usr/lib/systemd/system/vramswap.service
[Unit] Description=Swap on Video RAM [Service] Type=oneshot ExecStart=/usr/bin/mkswap /dev/mtdblock0 ExecStart=/usr/bin/swapon /dev/mtdblock0 -p 10 ExecStop=/usr/bin/swapoff /dev/mtdblock0 RemainAfterExit=yes [Install] WantedBy=multi-user.target
mtdblock
设备,请使用 cat /proc/mtd
查找名称为 VRAM 的 mtdblock
。Xorg 驱动配置
为了保持 X 的稳定,需要告知您的视频驱动程序使用少于检测到的显存。
/etc/X11/xorg.conf.d/vramswap.conf
Section "Device" Driver "radeon" # or whichever other driver you use VideoRam 32768 #other stuff EndSection
上面的示例指定您使用 32 MB 的显存。
故障排除
以下命令可能有助于您获取不同空间(如磁盘分区、闪存盘以及可能的显存交换示例)中已使用的交换空间
swapon -s
参见
FUSE 文件系统
此方法适用于具有 OpenCL 支持的硬件,使用 FUSE 文件系统支持的交换文件。有关更多信息,请参见GPGPU。
配置
首先,安装 vramfs-gitAUR。然后,创建一个空目录作为挂载点(例如 /tmp/vram
)。
现在运行以下命令来设置 vramfs 和交换文件。
# vramfs /tmp/vram 256MB -f # Substitute 256M with your target vramfs size # mkswap -U clear --size 200M --file /tmp/vram/swapfile # Substitute 200 with your target swapspace size in MiB
您的交换空间现在应该准备好了。运行 swapon
进行检查。
有关更多信息,请参见Swap#交换文件。
/tmp/vram
用作临时存储,很像 Tmpfs。设置 swappiness
在显存上使用交换空间的情况下,增加 swappiness 可能是一个好主意。当 VRAM 交换文件的随机 I/O 速度明显快于随机磁盘 I/O 时尤其如此,因为缓存磁盘读取的好处将超过交换的成本。例如,如果您的随机磁盘 I/O 速度与 VRAM 交换 I/O 相同,则应将 swappiness 设置为 100。如果 VRAM 交换 I/O 速度比磁盘 I/O 快 2 倍,则应将 swappiness 设置为 133。有关如何正确计算 swappiness 值,请参见内核文档。
故障排除
swapon: /tmp/vram/swapfile: 跳过 - 它似乎有空洞。
创建的交换文件不是连续的。可以设置一个循环设备来解决此问题。
# cd /tmp/vram # LOOPDEV=$(losetup -f) # truncate -s 4G swapfile # replace 4G with target swapspace size, has to be smaller than the allocated vramfs # losetup $LOOPDEV swapfile # mkswap $LOOPDEV # swapon $LOOPDEV
高内存压力下系统完全冻结
有时,在高内存压力下,vramfs
进程本身可能会被交换到 VRAM 交换空间。这会导致完全死锁。一个解决方法是通过 cgroups 使该进程不可交换,方法是通过 systemd 文件启动它
/etc/systemd/system/vramswap.service
[Unit] Description=Set up swap in VRAM After=default.target [Service] Type=oneshot RemainAfterExit=yes # Change /root/vramswap.sh to a path to a script that performs all the necessary setup ExecStart=/root/vramswap.sh TimeoutStartSec=0 # Prevent swapping MemorySwapMax=0 [Install] WantedBy=default.target