﻿# 把游戏本独显驯成只在需要时醒来的计算卡

> 一次把幻 16 Air 2025 上的 RTX 5070 Ti 从桌面渲染里摘出来，只保留 CUDA 计算能力的排障记录。

- Canonical: https://vimalinx.com/posts/%E6%8A%8A%E6%B8%B8%E6%88%8F%E6%9C%AC%E7%8B%AC%E6%98%BE%E9%A9%AF%E6%88%90%E5%8F%AA%E5%9C%A8%E9%9C%80%E8%A6%81%E6%97%B6%E9%86%92%E6%9D%A5%E7%9A%84%E8%AE%A1%E7%AE%97%E5%8D%A1.html
- Published: 2026-05-08T11:20:00+08:00
- Updated: 2026-05-08T11:21:03+08:00
- Category: 技术笔记
- Tags: Arch Linux, NVIDIA, 笔记本续航, Hyprland, TLP
- Reading time: 5 min read

---

## 问题不是“Linux 续航差”这么简单

这次折腾的起点很朴素：同一台机器，Windows 下中度使用还能撑四五个小时，Arch Linux 下离电省电之后却只剩一小时二十分钟左右。

机器是幻 16 Air 2025，Intel Core Ultra 9 285H 加 RTX 5070 Ti Laptop GPU。我的目标并不是把独显彻底禁掉，因为它对 CUDA、AI 推理、渲染和一些计算任务仍然有价值。我真正想要的是：

- 桌面显示只走核显。
- 普通 GUI 程序默认不碰独显。
- 独显只作为计算卡存在。
- 空载时独显必须能 runtime suspend。
- 需要 CUDA 或显式查询时再自动唤醒，用完自动睡回去。

这几个目标看起来很自然，但在 Linux 混合显卡环境里，它们不是同一件事。

## 先分清三种“独显没用”

排障时最容易误判的地方，是把下面三种状态混在一起：

第一种是独显不负责显示。内屏接在核显上，`nvidia-smi` 里 `Display Active` 也不是 active。这只能说明它不是显示卡。

第二种是没有用户进程打开 `/dev/nvidia0` 或 `/dev/dri/renderD*`。这说明当前没有普通应用直接占用独显。

第三种才是最关键的：PCI 设备本身进入 runtime suspend。也就是：

```bash
cat /sys/bus/pci/devices/0000:01:00.0/power/runtime_status
```

输出应该是：

```text
suspended
```

前两种状态都成立时，独显仍然可能保持 P8、空载烧几瓦电。我的机器一开始就是这种状态：桌面看起来没用独显，但 NVIDIA 仍然 active。

## 第一刀：别让桌面和 GLVND 枚举 NVIDIA

Hyprland 配置里写 `env = DRI_PRIME,0` 不够。这个变量主要影响 Hyprland 启动后的子进程，而 Hyprland 自己在启动阶段就可能通过 GLVND 枚举到 NVIDIA EGL vendor，然后加载 `libEGL_nvidia.so` 一类库。

最后有效的是给 Hyprland 的 systemd user unit 加 drop-in，让它在进程启动前就只看 Mesa EGL vendor：

```ini
[Service]
Environment=__EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/50_mesa.json
Environment=DRI_PRIME=0
UnsetEnvironment=__NV_PRIME_RENDER_OFFLOAD __GLX_VENDOR_LIBRARY_NAME GBM_BACKEND LIBVA_DRIVER_NAME NVD_BACKEND
```

我的文件位置是：

```text
~/.config/systemd/user/wayland-wm@hyprland.desktop.service.d/10-force-mesa-egl.conf
```

重登之后验证：

```bash
pid=$(pidof Hyprland | awk '{print $1}')
rg -i 'nvidia|libcuda' /proc/$pid/maps
lsof -nP /dev/nvidia0 /dev/nvidiactl
```

都应该没有输出。这里的重点不是“核显优先”，而是让 compositor 自己别在启动时顺手碰一下 NVIDIA。

## 第二刀：不要启动 NVIDIA 图形栈

我的目标是计算卡，不是 PRIME 图形 offload。所以 `nvidia_drm` 和 `nvidia_modeset` 对这个目标反而是负担。

我做了三件事。

先从 initramfs 的早期模块列表里移除 NVIDIA 图形栈。原来 `/etc/mkinitcpio.conf` 里有：

```text
MODULES=( nvidia nvidia_modeset nvidia_uvm nvidia_drm )
```

改成不预加载这些模块，然后：

```bash
sudo mkinitcpio -P
```

再加一个 modprobe 配置，把 NVIDIA DRM/modeset 挡住，只保留核心驱动给 CUDA 使用：

```ini
# /etc/modprobe.d/zz-nvidia-compute-only.conf
blacklist nvidia_drm
blacklist nvidia_modeset
install nvidia_drm /usr/bin/false
install nvidia_modeset /usr/bin/false

options nvidia NVreg_DynamicPowerManagement=0x02
options nvidia_drm modeset=0 fbdev=0
```

最后把 `nvidia-utils` 默认开机加载 `nvidia-uvm` 的行为盖掉：

```bash
sudo ln -sfn /dev/null /etc/modules-load.d/nvidia-utils.conf
```

这样重启后，`nvidia_drm` 和 `nvidia_modeset` 不再出现：

```bash
lsmod | grep '^nvidia_drm\|^nvidia_modeset'
```

无输出才是我想要的状态。

## 第三刀：TLP 的 performance 档也不能把计算卡点亮

最隐蔽的问题在 TLP。

我当时已经做到 Hyprland 不碰 NVIDIA，`nvidia_drm` 和 `nvidia_modeset` 也不加载，甚至卸掉 `nvidia_uvm` 后，独显还是 active。最后发现真正卡住它的是：

```text
/sys/bus/pci/devices/0000:01:00.0/power/control = on
```

原因是 TLP 的 AC/performance 配置里有：

```ini
RUNTIME_PM_ON_AC=on
```

这个配置对大部分性能档场景合理，但对“只作为计算卡的独显”不合理。计算卡空载也应该睡眠，不应该因为插电或 performance 档就常亮。

解决方法是给 NVIDIA 两个 PCI function 单独开 runtime PM：

```ini
# /etc/tlp.d/02-nvidia-compute-only.conf
RUNTIME_PM_ENABLE="01:00.0 01:00.1"
```

然后：

```bash
sudo tlp start
```

这一步验证非常直接：

```bash
cat /sys/bus/pci/devices/0000:01:00.0/power/control
cat /sys/bus/pci/devices/0000:01:00.0/power/runtime_status
```

目标输出：

```text
auto
suspended
```

这里有个小坑：TLP 配置行不能缩进。前面多两个空格，`tlp-stat -c` 就不会识别它。

## 验证要避免自己把独显唤醒

很多 NVIDIA 检查命令本身会唤醒独显，尤其是：

```bash
nvidia-smi
```

所以日常判断独显睡没睡，优先看 sysfs：

```bash
cat /sys/bus/pci/devices/0000:01:00.0/power/runtime_status
```

我最后的稳定状态是：

```text
supergfxctl = Hybrid
01:00.0 NVIDIA GPU = control auto, runtime suspended
01:00.1 NVIDIA audio = control auto, runtime suspended
Hyprland = 无 NVIDIA 库、无 /dev/nvidia* 句柄
TLP = 已读取 RUNTIME_PM_ENABLE="01:00.0 01:00.1"
```

我还做了一次受控唤醒测试：先确认空载是 `suspended`，再运行 `nvidia-smi`。独显会短暂醒来，随后在没有用户进程持有的情况下自动回到 `suspended`。

这就说明目标达成了：它不是被永久禁用，而是按需唤醒的计算卡。

## 代价和边界

这套方案不是“最通用”的混合显卡方案，而是有明确取舍的 compute-only 方案。

代价很清楚：

- `prime-run` 这类 NVIDIA 图形 offload 不再是默认目标。
- 如果外接屏物理接在独显输出上，可能不可用。
- 某些依赖 NVIDIA EGL/GLX 的 GUI 工作流需要单独恢复图形栈。
- `nvidia-smi` 会唤醒独显，不能拿它当无干扰监控。

但换来的状态也很干净：

- 桌面渲染归核显。
- 普通应用不会把独显误唤醒。
- CUDA/计算仍能用。
- 独显空载真正 runtime suspend。
- TLP 的 performance/AC 档也不会把它强行保持在 `on`。

对我这类“核显足够强，独显主要用于计算”的使用方式来说，这比来回切 MUX、注销、重启更符合日常。

## 最后真正耗电的是别的东西

独显睡下去之后，整机功耗确实下降了。后来再看功耗，独显已经不再是问题，新的大头变成了 240Hz 屏幕、浏览器、Hyprland、Waybar、多个 Codex/OMX watcher、开发服务和微信这些常驻任务。

这也算是一个提醒：笔记本续航排障不要只盯着一个“嫌疑犯”。独显常亮很刺眼，也确实该处理；但它睡下去以后，系统里那些看似不起眼的后台和高刷新屏幕，才会成为下一层瓶颈。

调电源管理就是这样，一层一层剥。先把最离谱的错误状态纠正，再看真实工作负载。
