如果你手里是一张 RX 580 8GB、RX 6500 XT 4GB,或者矿潮时期淘来的二手卡,大概率经历过这种绝望:游戏正打到关键处,画面突然卡死,整个桌面都冻住了,鼠标都动不了,只能硬重启。

这不是显卡不行,是显存不够用了。现在的 3A 大作动辄要 8GB 甚至 12GB 显存,4GB 的卡连最低画质都跑得战战兢兢。
8GB 看着还行,但桌面合成器、浏览器、Discord 这些后台玩意儿也在偷偷吃你的 VRAM。等你进游戏的时候,真正能用的可能就剩 6GB。
Windows 用户至少有个缓冲,显存不够了系统会自动往内存里挪,虽然会卡一下但不会直接死给你看。Linux 用户呢?不好意思,amdgpu 驱动处理 VRAM 超限的方式比较"直接粗暴":要么卡死,要么崩溃。
为什么 Linux 下显存管理这么拉胯?
要理解这个问题,得先知道 Windows 和 Linux 在显存管理上的根本区别。
Windows 有个叫 WDDM 的显示驱动模型,它把显存做了一层虚拟化。简单说,应用程序看到的不是物理显存地址,而是一个虚拟地址空间。物理 VRAM 不够的时候,WDDM 会自动把一部分数据挪到系统内存里,对应用程序完全透明。就像你的抽屉满了,旁边还有个箱子可以临时放东西,拿起来慢一点,但至少不会把抽屉撑爆。
Linux 下的 amdgpu 驱动用的是 TTM(Translation Table Maps)内存管理器。它也支持 VRAM 和系统内存之间的数据迁移,但问题是它不够聪明。多个应用抢显存的时候,没有优先级调度机制,后台的 Firefox 和前台的游戏在驱动眼里地位一样。就像一个没有排队的食堂,谁抢到算谁的,结果打游戏这个正事反而没位置坐。
更具体地说:
Windows (WDDM):
┌─────────────────────────┐
│ 应用层 │ → 只看到虚拟 GPU 地址
├─────────────────────────┤
│ WDDM 虚拟化层 │ → 自动分页、TDR 恢复、超额承诺
├─────────────────────────┤
│ 物理显存 / 系统内存 │ → 统一管理,智能调度
└─────────────────────────┘
Linux (amdgpu + TTM):
┌─────────────────────────┐
│ 应用层 │ → 需要自己管理 buffer 放置策略
├─────────────────────────┤
│ TTM 内存管理器 │ → 支持 VRAM↔GTT 迁移,但粒度粗
├─────────────────────────┤
│ 物理显存 / GTT(系统内存) │ → 无优先级,多应用竞争无序
└─────────────────────────┘
所以你看,不是 Linux 内核不行,是 GPU 资源管理这块长期没人好好搞。
内核社区其实一直在讨论 drm cgroup 的提案,想把 GPU 资源纳入 cgroups 管理,但推进速度嘛……你懂的,内核社区的节奏一向是"快了快了,再等几年"。
Natalie Vock 的方案:用 cgroups 给显存排个队
就在大家都在等内核社区慢慢推进的时候,有个叫 Natalie Vock(网名 pixelcluster)的开发者站出来说:我来搞。
她的方案核心思路其实很直觉:用 cgroups 给进程分配显存配额,让后台应用不能无限制地抢 VRAM。前台游戏有足够的显存用,后台的浏览器什么的该让路就让路。
打个比方:以前显存就像公共停车场,谁先来谁占,有些车停了一整天不动,真正需要停的车反而找不到位置。
Natalie 的方案就是给停车场装了个智能管理系统,前台的车辆优先保证车位,后台的车辆在车位紧张时自动挪走。
具体来说,这套方案包含这些部分:
内核层面:dmem cgroup 控制器 + 6 个内核补丁
dmem 是一个新的 cgroup 控制器,专门用来管理设备的内存资源(Device Memory),GPU 显存就是其中最重要的场景。这 6 个补丁修改了内核的 cgroup 框架和 DRM 子系统,让它们能够追踪和控制每个 cgroup 的显存使用量。
用户空间:两个辅助工具
- dmemcg-booster:一个守护进程,监控系统内存和显存压力,在紧张时自动将后台进程的显存迁移到系统内存。相当于停车场的调度员,发现车位不够就主动联系停了好久的车主挪车。
- plasma-foreground-booster:专门为 KDE Plasma 桌面设计的工具,它会追踪当前聚焦的窗口,自动把前台应用的 cgroup 优先级调高。你在打游戏的时候,游戏的显存配额自动提升,后台应用的配额自动降低。
整个架构大概是这样:
┌──────────────────────────────────────────┐
│ 用户空间 │
│ ┌─────────────┐ ┌─────────────────────┐ │
│ │dmemcg-booster│ │plasma-foreground- │ │
│ │(显存调度守护) │ │booster(前台优先) │ │
│ └──────┬──────┘ └──────────┬──────────┘ │
│ └──────────┬─────────┘ │
│ ▼ │
│ ┌──────────────────────────────────────┐ │
│ │ dmem cgroup 控制器 │ │
│ │ (追踪每个进程组的显存使用量) │ │
│ └──────────────────────────────────────┘ │
├──────────────────────────────────────────┤
│ 内核空间 │
│ ┌──────────────┐ ┌───────────────────┐ │
│ │ cgroup 核心 │ │ DRM/amdgpu 驱动 │ │
│ │ (6个补丁增强) │ │ (显存分配追踪) │ │
│ └──────────────┘ └───────────────────┘ │
└──────────────────────────────────────────┘
说实话,我觉得这个思路非常对路。与其等内核社区慢慢推 drm cgroup,不如先用一个更聚焦的方案解决实际问题。
cgroups 本身就是 Linux 的标准机制,不会引入什么奇怪的黑科技,稳定性和可维护性都有保障。
效果如何?数据说话
光说原理没用,得看实际效果。Natalie 在她的博客里给出了 Cyberpunk 2077 的测试数据:
GTT(Graphics Translation Table,即映射到系统内存的显存数据)使用量:从 1.6GB 降至 650MB
这个数据意味着什么?GTT 内存高说明有大量数据被从 VRAM 驱逐到了系统内存,通常意味着物理显存严重不足。把 GTT 从 1.6GB 压到 650MB,也就是说有将近 1GB 的数据从系统内存"回流"到了显存,因为后台进程不再霸占显存了。
用大白话说:游戏能用的显存多了将近 1GB,而且是从系统内存挪回来的,访问速度快了很多。 对于一张 4GB 或 8GB 的卡来说,1GB 的差距可能就是"能玩"和"不能玩"的区别。
当然,这只是单个游戏的测试数据,不同游戏效果可能会有差异。但方向是对的,让该用显存的进程用上显存,不该占着的赶紧让出来。
想尝鲜?CachyOS 用户已经能开箱即用了
好消息是,这个方案不是纸上谈兵。CachyOS 已经把相关补丁集成到了他们的内核里。
CachyOS 内核 7.0rc7-2 及以上版本已经包含了 dmem cgroup 控制器的补丁。你只需要安装两个包:
sudo pacman -S dmemcg-booster plasma-foreground-booster
装完启用服务就行了。不用改内核参数,不用手动配 cgroup,基本是开箱即用。
目前支持的 GPU 驱动:
如果你用的是其他发行版,理论上也能用,但需要自己打内核补丁、编译内核。这个门槛就比较高了,建议等补丁合入主线或者各发行版跟进。
写在最后:小显存不等于该退役
说到底,小显存显卡的问题很多时候不是"性能不够",而是"资源分配不合理"。一张 RX 580 8GB 的计算能力其实还能打很多游戏,但显存管理不到位导致大量资源被后台进程浪费,游戏反而跑不动。
Natalie Vock 的这个方案从根本上改善了 Linux 下 GPU 显存的分配逻辑。它不是给显卡加显存,而是让现有的显存被更合理地使用。对 Linux 游戏玩家来说,这是个实打实的利好。
我个人觉得,这个方案的意义不只是让老卡多续几年命。它其实给 Linux GPU 资源管理指了一个方向:与其给每个驱动单独做优化,不如在内核层面建立一个统一的资源管理框架。cgroups 在 CPU 和内存管理上已经被证明是成功的,把它扩展到 GPU 领域是自然而然的事情。
如果你是 Linux 游戏玩家,手里又是一张显存不太富裕的 AMD 卡,强烈建议关注这个项目。博客原文可以点击“阅读原文”,写得非常详细,值得一读。