博客

把幻16 Air 2025调成自己的 Arch 移动工作站

这次像给机器重新排线

这次折腾的起点很简单,也很气人。

同一台机器,Windows 下中度使用还能撑四五个小时,到了 Arch Linux 这边,明明已经开了省电,离电之后却只剩一小时二十分钟左右。负载也没到 3A 游戏那种强度,只是几个 Codex、浏览器、开发服务和日常桌面。按理说 Arch 不应该这么离谱。

机器是幻 16 Air 2025,也就是 ASUS ROG Zephyrus G16 GU605CR。核心配置是 Intel Core Ultra 9 285H 加 RTX 5070 Ti Laptop GPU,内屏 2560x1600 高刷,系统是 Arch Linux,桌面是 Hyprland。

一开始我的问题是:为什么这么耗电?

后来问题慢慢变成:我要怎样让这台机器按照我的工作流耗电?

最后形成的目标是:

  • 日常桌面只用核显显示。
  • 独显不再参与桌面渲染,只作为计算卡存在。
  • 独显空闲时必须能 runtime suspend。
  • F5 能在 ASUS 平台档和 TLP 电源档之间联动切换。
  • quiet 档自动切到 60Hz。
  • quiet 档在没有蓝牙设备连接时自动关蓝牙。
  • quiet 档把 CPU 性能上限压到 20%,但不影响日常写代码和浏览。
  • 充电阈值交给热键,在 60/80/100 之间切。
  • 睡觉或挂机时用 Super+X 关屏,不关机。

最后调出来以后,这台机器才开始有点“自己的 Arch 笔记本”的样子。原来的默认配置像一团散线;调完以后,每一层策略都重新接回我手上。

第一阶段:先别相信“省电模式”三个字

最开始我以为自己已经开了省电。

但笔记本上的“省电模式”可能指很多东西:

  • 桌面环境显示的 power profile。
  • ASUS 固件里的 platform profile。
  • CPU 的 governor 或 EPP。
  • 是否禁用 turbo。
  • Wi-Fi 是否开 power save。
  • PCIe 设备是否 runtime PM。
  • 屏幕刷新率有没有降。
  • 蓝牙有没有关。
  • 独显到底有没有睡着。
  • 后台有没有编译器、浏览器 GPU process 或 watcher 在烧 CPU。

这些东西像一排独立拨杆。一个拨杆推到“省电”,整台机器也可能还在另一边漏电。

这也是这次最大的经验之一:笔记本续航排障不能只看 UI 上的档位,必须拆成几个层面逐项验证。

我的基础检查后来固定成这几类。

看 ASUS 平台档:

cat /sys/firmware/acpi/platform_profile

看 TLP 当前档:

tlp-stat -s

看 CPU 是否真的被压住:

cat /sys/devices/system/cpu/intel_pstate/max_perf_pct
cat /sys/devices/system/cpu/intel_pstate/no_turbo
cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference

看独显到底有没有睡着:

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

看实际功耗:

upower -i /org/freedesktop/UPower/devices/battery_BAT1 | grep -E 'energy-rate|percentage|time to empty'

或者直接从 sysfs 读电压和电流算:

cat /sys/class/power_supply/BAT1/current_now
cat /sys/class/power_supply/BAT1/voltage_now

先有这些证据,后面才知道自己到底是在优化,还是在心理安慰。

PPD、TLP、tuned:最后我选了 TLP

我一开始也看了网上常见建议:power-profiles-daemon、TLP、auto-cpufreq、Powertop、tuned。

这些工具各管一段管线,拧错地方就像拿水龙头去调电闸。

power-profiles-daemon 的优点是简单,和桌面环境集成好,适合“性能、平衡、省电”三个档位的轻量切换。但它的颗粒度太粗。我要控制的是 CPU EPP、CPU 最大性能百分比、PCI runtime PM、NVIDIA 独显 runtime suspend、Wi-Fi、省电档映射、平台 profile 联动。PPD 对这类机器不够细。

tuned 也可以做 profile,后来还有 tuned-ppd 这条路。它适合更通用的 profile 管理,但我这次最需要的是 TLP 对笔记本电源细项的成熟覆盖,以及和 tlp-pd 的 profile bridge。

auto-cpufreq 主要管 CPU 频率策略。它能改善一部分续航,但我的问题明显超出 CPU 范围。独显、屏幕、蓝牙、PCI runtime PM、后台负载都在里面。只用 auto-cpufreq 反而容易造成多个电源管理工具抢同一组旋钮。

所以最后我保留了 TLP 这条线:

sudo pacman -S --needed tlp tlp-pd tlp-rdw

安装时遇到的第一个坑是冲突:

tlp-pd and power-profiles-daemon are in conflict

这说明 PPD 和 tlp-pd 不能同时接管同一个 D-Bus power profile 接口。我的选择是移除 PPD,让 TLP 通过 tlp-pd 接到桌面的 power profile 体系里。

后来 TLP 的核心配置变成这样:

TLP_ENABLE=1
TLP_DEFAULT_MODE=AC
TLP_PERSISTENT_DEFAULT=0

PLATFORM_PROFILE_ON_AC=performance
PLATFORM_PROFILE_ON_BAT=balanced
PLATFORM_PROFILE_ON_SAV=quiet

CPU_DRIVER_OPMODE_ON_AC=active
CPU_DRIVER_OPMODE_ON_BAT=active
CPU_DRIVER_OPMODE_ON_SAV=active

CPU_SCALING_GOVERNOR_ON_AC=powersave
CPU_SCALING_GOVERNOR_ON_BAT=powersave
CPU_SCALING_GOVERNOR_ON_SAV=powersave

CPU_ENERGY_PERF_POLICY_ON_AC=balance_performance
CPU_ENERGY_PERF_POLICY_ON_BAT=balance_power
CPU_ENERGY_PERF_POLICY_ON_SAV=power

CPU_MIN_PERF_ON_AC=0
CPU_MAX_PERF_ON_AC=100
CPU_MIN_PERF_ON_BAT=0
CPU_MAX_PERF_ON_BAT=80
CPU_MIN_PERF_ON_SAV=0
CPU_MAX_PERF_ON_SAV=20

CPU_BOOST_ON_AC=1
CPU_BOOST_ON_BAT=0
CPU_BOOST_ON_SAV=0
CPU_HWP_DYN_BOOST_ON_AC=1
CPU_HWP_DYN_BOOST_ON_BAT=0
CPU_HWP_DYN_BOOST_ON_SAV=0

PCIE_ASPM_ON_AC=default
PCIE_ASPM_ON_BAT=default
RUNTIME_PM_ON_AC=on
RUNTIME_PM_ON_BAT=auto

这里有两个点很关键。

第一,intel_pstate 在 active 模式下,governor 显示 powersave 并不等于机器被锁死成低性能。真正影响体验的是 EPP、max_perf_pct、turbo、平台 profile 这些组合。

第二,我没有把电池充电阈值写死进 TLP。这台机器有时在桌上挂机,有时又要带出门;出门前要充到 100%。充电阈值更像临出门前拧的旋钮,不适合落成 TLP 里的永久配置。

F5 要把 ASUS 档和 TLP 一起拉动

ROG 机器上 F5 会让人以为自己已经完成了电源模式切换,但实际上 ASUS platform profile 和 TLP profile 是两套东西。

我最后想要的逻辑是:

ASUS Performance -> TLP performance -> 240Hz -> 键盘背光高 -> blur 开
ASUS Balanced    -> TLP balanced    -> 240Hz -> 键盘背光中 -> blur 开
ASUS Quiet       -> TLP power-saver -> 60Hz  -> 键盘背光低 -> blur 关 -> 空闲蓝牙关闭

这就不能只靠系统默认行为了,需要脚本把几个层面一起切。

最终 F5 脚本做了这些事:

  • 读取当前 asusctl profile get
  • 在 Quiet、Balanced、Performance 之间循环。
  • 调用 tlpctl set performance/balanced/power-saver 同步 TLP。
  • 调用 asusctl profile set 切 ASUS 平台档。
  • 调整键盘背光。
  • 调整 Hyprland blur。
  • 调整内屏刷新率。
  • Quiet 档检查蓝牙连接数,没有连接就关蓝牙。

这里踩了一个很典型的坑:内屏名字写死。

我一开始以为内屏是 eDP-2,实际当前机器里是 eDP-1。显示名错了以后,脚本看起来在切档,但刷新率没有正确落地,甚至会让人误以为“怎么按都只有平衡”或者“quiet 档没反应”。

最后脚本改成先探测内屏,绕开 eDP-1eDP-2 这种易变名字:

hyprctl monitors -j \
  | jq -r 'map(select(.name | test("^(eDP|LVDS|DSI)-"))) | .[0].name // empty'

找不到再退回第一个 monitor。这个改动很小,但特别重要,因为 Wayland 下显示名长期硬编码很靠不住。

60Hz 是续航里最立竿见影的一刀

这块非常直观。

一开始这块屏幕跑高刷,功耗下不去。后来 quiet 档切 60Hz 之后,用户体感最明显的一次数据是:40 分钟掉了 15% 电。粗略折算满电大概 4 小时 27 分钟,平均功耗大概 20W 左右。

这件事没有玄学,但很实用。游戏本上的高分辨率高刷屏,本身就是一块长期亮着的耗电板。CPU 限频、Wi-Fi 省电、蓝牙关闭这些当然有价值;在日常浏览和写代码场景里,刷新率通常是最好下刀的地方。

最后 quiet 档固定做:

2560x1600@60

balanced 和 performance 保持:

2560x1600@240

这个取舍很合理。离电写东西、看文档、跑 Codex,不需要 240Hz。需要丝滑的时候再切回 balanced 或 performance。

蓝牙策略:像门卫一样,看见没人再熄灯

蓝牙也不能简单粗暴。

如果正在连鼠标、耳机、手柄,切 quiet 档就把蓝牙关掉,那体验会很差。但如果没有设备连接,蓝牙开着就是无意义后台。

所以脚本用了这个判断:

bluetoothctl devices Connected

有连接就保持开启。没有连接就:

rfkill block bluetooth

这套策略的边界很清楚:先保住工作流,再让系统在空闲缝隙里自己节制。

后来实际验证 quiet 档时,蓝牙状态能显示成 soft blocked,这就是预期。

CPU 压到 20% 以后,机器居然还能正常用

这件事挺有意思。

最开始 quiet 档的 CPU 上限没有那么狠,后来我觉得现在这些任务不怎么吃 CPU,就继续往下砍。先从 60% 往下,最后试到了 20%。

当前 quiet 档的关键状态是:

max_perf_pct=20
no_turbo=1
epp=power
ASUS profile=quiet
TLP profile=power-saver/SAV

看起来很残忍,但机器仍然能正常跑。20% 上限听着像把电脑塞回老上网本,实际限制的是 P-state 性能区间和 turbo 行为。核心仍然会被调度,系统也照样转,只是油门行程被垫了一块木头。

对 Core Ultra 9 285H 这种 CPU 来说,20% 的可用性能已经足够支撑:

  • 终端。
  • 浏览器普通页面。
  • Codex 对话。
  • Markdown 写作。
  • 轻量脚本。
  • Hyprland 桌面。

当然,它不适合编译大项目、不适合跑模型、不适合大规模 Playwright、不适合高负载浏览器页面。这个档位的定义很清楚:离电、安静、轻工作。

这也让我暂时没有去做“关 P 核,只留 E 核”的方案。理论上可以继续折腾 CPU affinity、cpuset、systemd slice、甚至离线部分 CPU,但那会变得脆弱很多。现在 TLP 的 max_perf_pct、禁 turbo、EPP power 已经足够稳定,也不容易把系统搞坏。

独显问题:这张卡该像仓库里的电焊机

这次最大的坑还是独显。

我并不想把 RTX 5070 Ti 彻底禁掉。它在这台机器上非常有价值,可以跑 CUDA、AI 推理、视频和图形计算。问题是日常写代码和浏览网页的时候,它不应该参与显示,也不应该空载常亮。

目标更像给独显安排一张班表:

核显负责显示
独显只做计算卡
不用时 runtime suspended
需要 CUDA 时自动醒
用完之后自动睡回去

这个目标和普通的 “PRIME offload” 不完全一样。PRIME offload 关注的是某个 GUI 程序是否用 NVIDIA 渲染。我这次更关心的是:桌面和普通 GUI 程序永远不要碰 NVIDIA,NVIDIA 只给计算任务用。

判断独显有没有睡,不能只看 nvidia-smi

最可靠的是:

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

目标输出是:

suspended
suspended

其中 01:00.0 是 NVIDIA GPU,01:00.1 是 NVIDIA 音频 function。两个都应该能睡。

nvidia-smi 本身会把独显叫醒

这也是一个非常容易误判的坑。

你想看独显睡没睡,于是运行:

nvidia-smi

然后独显醒了。

于是你以为独显没睡。

其实是检查动作本身把它唤醒了。

所以后来我日常检查独显状态时绕开 nvidia-smi,直接看 sysfs:

for dev in /sys/bus/pci/devices/0000:01:00.0 /sys/bus/pci/devices/0000:01:00.1; do
  echo "$(basename "$dev") control=$(cat "$dev/power/control") status=$(cat "$dev/power/runtime_status")"
done

如果看到:

0000:01:00.0 control=auto status=suspended
0000:01:00.1 control=auto status=suspended

这才是它睡着的证据。

现在机器上即使 nvidia_uvm 模块还在,只要使用数是 0,同时 PCI runtime status 是 suspended,就不代表独显在烧电。nvidia_uvm 可以理解成 CUDA 计算的入口模块;模块加载只是门口挂了牌,屋里的灯未必亮着。

TLP 的 performance 档差点把独显固定点亮

这次最隐蔽的坑在 TLP。

我一开始已经把很多东西都排掉了。Hyprland 不该用 NVIDIA,普通进程也没明显占用 NVIDIA,甚至卸掉 nvidia_uvm 之后,独显还是 active。

后来看到:

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

这才意识到,真正扳住电源开关的地方不在进程列表里,卡在 TLP 的电源策略里。

TLP 的 performance/AC 档里有:

RUNTIME_PM_ON_AC=on

对普通性能档来说这很正常,插电性能优先,不积极 suspend PCI 设备。但对我的目标来说不对。独显既然只是计算卡,哪怕在 performance 档,只要没任务,也应该睡。

最后加了一个单独的 TLP drop-in:

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

这个配置的意义是:即使全局 AC/performance 档偏向保持设备 on,也允许这两个 NVIDIA PCI function 使用 runtime PM。

验证过程很直接:

sudo tlp start
sleep 20
cat /sys/bus/pci/devices/0000:01:00.0/power/control
cat /sys/bus/pci/devices/0000:01:00.0/power/runtime_status

目标是:

auto
suspended

最后这个状态稳定了。也就是说,performance 档不会再无脑点亮计算卡。

TLP 配置行不要缩进,shell 引号也别乱写

这次还有一个特别土但特别真实的坑:写配置写错。

有一次我用 heredoc 写:

sudo tee /etc/tlp.d/02-nvidia-compute-only.conf >/dev/null <<'EOF'
  # Keep compute-only NVIDIA dGPU asleep even on AC/performance.
  RUNTIME_PM_ENABLE="01:00.0 01:00.1"
EOF

看起来很像对了,但实际配置行前面有空格。TLP 对配置格式比 shell 严得多,前面多出来的缩进会让配置不被按预期解析。

另一次我用 printf 包在 sudo sh -c 里面,换行和引号没处理好,结果 shell 把:

RUNTIME_PM_ENABLE="01:00.0 01:00.1"

当成了要执行的命令,直接报:

command not found

最后最稳的方法是写成一个 root 脚本:

cat > /etc/tlp.d/02-nvidia-compute-only.conf <<'EOF'
# Keep compute-only NVIDIA dGPU asleep even on AC/performance.
RUNTIME_PM_ENABLE="01:00.0 01:00.1"
EOF

tlp start

这种事情看起来很小,但电源调校就是这样:一个空格、一层引号、一个错误的设备名,都能让你查半天。

nvidia_drm is in use 说明不要硬拔图形栈

中间我也试过卸载 NVIDIA DRM 模块:

sudo modprobe -r nvidia_drm

结果是:

modprobe: FATAL: Module nvidia_drm is in use.

这个报错本身不奇怪。只要 compositor、显示栈或某个图形组件碰过它,它就可能被占着。此时强行在线拆模块,路线会非常别扭。

后来我放弃了“运行时把所有图形栈拔掉”的思路,改成更稳定的方案:

  • 让桌面默认走核显。
  • 让独显保持 Hybrid 下的 compute-only 使用方式。
  • 让 TLP 对 NVIDIA PCI function 开 runtime PM。
  • 接受需要图形模式切换时通过注销或重启处理。

这个取舍很重要。为了少注销一次,把显示栈在线拆来拆去,很可能把系统搞得更脆弱。目标落在日常稳定上,没必要拿 Linux 显卡栈当靶场。

后来真正耗电的是浏览器和开发服务

独显睡下去之后,问题并没有完全结束。

有一次我觉得电越掉越快,就重新看功耗。结果设置都生效了:

ASUS profile = quiet
TLP profile = power-saver/SAV
CPU max_perf_pct = 20
no_turbo = 1
EPP = power
dGPU = suspended
Bluetooth = blocked
Wi-Fi power save = on
screen = 60Hz

但整机还是有 27W 到 36W。

这时候就不能再怪 TLP 或独显了。实际后台负载里有:

  • Chromium GPU process 瞬时冲到 100% 以上 CPU。
  • Chromium renderer 占用很高。
  • GradleDaemon 在跑。
  • KotlinCompileDaemon 在跑。
  • Hyprland 有明显 CPU 占用。
  • Waybar 有持续刷新。
  • 闲鱼自动化脚本在后台。
  • OMX notify watcher 在轮询。
  • WeChat、Clash、Codex 多实例也都在叠加。

这就是另一个教训:省电策略只能限制硬件行为,不能把真实负载变成不存在。

如果浏览器某个标签页、Gradle daemon、Kotlin daemon 或 Playwright 真的在干活,功耗就会上去。哪怕 CPU 被限制到 20%,只要负载持续,电也会掉得快。

后来我对续航测试的看法变成这样:

先确认平台和硬件策略正确
再做干净负载基准
最后才讨论真实工作流续航

否则很容易把“后台有东西在烧”误判成“Linux 省电没调好”。

功耗数字比预计剩余时间更诚实

笔记本电池百分比有时候会让人焦虑,尤其电量低于 30% 以后,电压曲线和系统估算都会让人感觉掉得更快。

我后来更相信瓦数。

粗略换算很简单。这台机器电池满电大约 86Wh 左右:

86Wh / 20W = 4.3h
86Wh / 26W = 3.3h
86Wh / 35W = 2.4h

这比“还有几小时几分钟”的 UI 估计更适合判断优化有没有效果。

这次有几个阶段数据很有代表性:

  • 最开始离电省电只有约 1h20m,明显不正常。
  • 后来 80% 到 20% 用了 2h03m,折算满电约 3h25m,平均约 26W。
  • 切到 60Hz 后,40 分钟掉 15%,折算满电约 4h27m,平均约 20W。
  • 后台负载高的时候,即使省电策略全对,仍然能到 27W 到 36W。

这几个数字说明一件事:系统策略和实际负载都重要。只修一个不够。

电池阈值应该交给热键,不应该写死

长期插电时,我希望电池停在 60%。这对电池健康更友好,尤其这台机器可能长时间开机、接电、关屏当移动工作站用。

但这不代表 TLP 配置里要永久写:

STOP_CHARGE_THRESH_BAT1=60

因为我还要出门。

出门前我需要按一下热键,把阈值切到 100%,让它充满。日常在家又可以切回 60% 或 80%。这更像背包出门前的最后一颗扣子,没必要缝死在固定系统策略里。

现有热键脚本的循环是:

80 -> 60 -> 100 -> 80

它写两个地方:

/sys/class/power_supply/BAT1/charge_control_end_threshold
/etc/battery_charge_limit

当前如果看到:

capacity=92
status=Not charging
threshold=60

这就是正常的。电池已经超过 60%,所以插电也不再继续充。

这里也踩过一个设计坑:我一度想把 60% 写进 TLP,后来意识到不对。因为这会把“临时出门要充满”的需求变麻烦。最后撤掉了 TLP 里的固定阈值,保留热键作为唯一入口。

这个选择我很满意。TLP 管电源策略,热键管人的意图。

24 小时开机没问题,但要关屏和保护电池

这台机器如果 24 小时开机,我并不担心 CPU 或主板先撑不住。

游戏本本来就是为高热密度设计的。只要通风正常,温度在合理范围内,60°C、70°C 对 CPU 来说并不可怕。真正要注意的是:

  • 长期插电时电池不要一直 100%。
  • OLED 或高亮静态屏幕不要一直亮。
  • 独显不要空载常醒。
  • 风道不要被堵。

我的挂机策略最后变成:

  • 插电长期使用时,充电阈值切到 60%。
  • 晚上睡觉按 Super+X,执行 Hyprland DPMS 关屏。
  • 需要亮屏时鼠标键盘唤醒。
  • 不关机,不折腾 suspend。
  • 独显继续保持 runtime suspended。

Super+X 对应的动作很简单:

hyprctl dispatch dpms off

这比让屏幕亮一整夜靠谱,也比为了省一点电频繁睡眠再唤醒更符合我的工作流。

为什么我没有继续追求“绝对最低功耗”

调到这里以后,其实还能继续榨。

比如:

  • Waybar 某些模块降低刷新频率。
  • 浏览器后台标签页冻结。
  • 自动停 Gradle/Kotlin daemon。
  • 自动停 OMX notify watcher。
  • quiet 档停掉更多用户服务。
  • 针对 Playwright 和开发服务做 battery mode wrapper。
  • 更激进地限制 CPU core 或进程 affinity。

但我暂时停了。

原因很简单:这台机器每天要干活,不能当实验板消耗。省电优化如果破坏了工作流,就失去了意义。

现在这套状态已经满足几个核心目标:

  • 默认不浪费独显。
  • quiet 档真的安静。
  • 离电轻工作续航能明显改善。
  • 插电长期使用有电池阈值保护。
  • F5 能把平台、电源、屏幕、蓝牙联动起来。
  • 需要性能时可以随时切回 balanced 或 performance。
  • 需要出门时可以用热键切 100% 充满。

这就够了。剩下的优化要等新痛点出现,别为了“再少 1W”把系统绕成迷宫。

最终我保留的几个脚本和配置

这次最后有价值的东西主要是这些。

TLP 主配置:

/etc/tlp.d/01-asus-g16-power.conf

它负责 ASUS 平台档映射、CPU EPP、CPU 上限、禁 turbo、TLP 的基础电源策略。

NVIDIA compute-only runtime PM:

/etc/tlp.d/02-nvidia-compute-only.conf

它保证 01:00.001:00.1 在空载时可以睡,不会因为 performance/AC 档就固定 on。

F5 档位切换:

~/.config/hypr/UserScripts/toggle-asus-profile.sh

它负责 ASUS profile、TLP profile、刷新率、键盘背光、blur、蓝牙策略的联动。

充电阈值热键:

~/.config/hypr/UserScripts/battery-toggle.sh

它负责在 80%、60%、100% 之间切换,不交给 TLP 写死。

关屏脚本:

~/.config/hypr/scripts/screen-off.sh

它用 DPMS 关屏,适合夜里挂机。

CPU quiet 上限脚本:

/home/vimalinx/apply-quiet-cpu-limit.sh

它把 TLP 的 CPU_MAX_PERF_ON_SAV 调成 20%,并立即应用。

NVIDIA TLP runtime 修复脚本:

/home/vimalinx/fix-nvidia-tlp-runtime.sh

它写入 NVIDIA runtime PM drop-in,并验证 control=autoruntime_status=suspended

这些脚本像几张贴在机器内部的标签:哪颗螺丝管 quiet,哪根线管独显,哪只按钮管出门充电。

我现在会怎样判断状态正常

如果以后重启、更新内核、升级 NVIDIA 或改 Hyprland,我会用这组检查快速判断有没有退化。

看平台和 TLP:

cat /sys/firmware/acpi/platform_profile
tlp-stat -s

quiet 档应该看到:

quiet
TLP profile = power-saver/SAV

看 CPU:

cat /sys/devices/system/cpu/intel_pstate/max_perf_pct
cat /sys/devices/system/cpu/intel_pstate/no_turbo
cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference

quiet 档目标:

20
1
power

看独显:

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

目标:

auto
suspended
suspended

看刷新率:

hyprctl monitors

quiet 档应该是 60Hz。

看蓝牙:

rfkill list bluetooth

没有设备连接时,quiet 档可以是 soft blocked。

看真实功耗:

upower -i /org/freedesktop/UPower/devices/battery_BAT1 | grep energy-rate

如果轻工作还是 25W 以上,就不要先怀疑 TLP,要先看:

ps -eo pid,ppid,stat,comm,%cpu,%mem,args --sort=-%cpu | sed -n '1,30p'

很多时候答案会是浏览器、编译器、开发服务、状态栏或 watcher。

这台机器最后变成了我想要的样子

这次折腾到最后,最让我满意的是整套逻辑终于对齐了。

以前的问题是每层都在各管各的:

  • ASUS 固件有一套 profile。
  • 桌面有一套 power profile。
  • TLP 有一套 profile。
  • Hyprland 有自己的显示配置。
  • NVIDIA 有自己的 runtime PM。
  • 蓝牙、Wi-Fi、屏幕、CPU 都各自散着。

看起来都在工作,但没有一个整体。

现在这几层被串起来了。

F5 从“风扇模式键”变成了我的工作状态切换键。

quiet 是真正的离电轻工作状态:60Hz、低背光、低 CPU、禁 turbo、EPP power、蓝牙空闲关闭、独显睡眠。

balanced 是日常插电或轻性能状态。

performance 是需要性能时的状态,但即使 performance,独显不用也能睡。

充电阈值是人的出行意图,不被 TLP 写死。

Super+X 是夜里挂机的关屏动作。

这才是我想要的 Arch 笔记本。默认配置并不完美,Arch 的好处在于它允许我把机器调成自己的样子。

最后留给未来自己的几句话

第一,不要看到续航差就立刻怪 Linux。先量瓦数,再看负载,再看硬件状态。

第二,不要相信“省电模式”这个抽象词。要分别验证 CPU、屏幕、蓝牙、Wi-Fi、PCI runtime PM、独显、后台进程。

第三,不要用 nvidia-smi 当无扰监控。它本身可能唤醒独显。

第四,TLP 很强,但不要什么都写死进 TLP。充电阈值这种需要随时切换的东西,留给热键。

第五,20% CPU 上限能用。对轻工作来说,它可能刚刚好。

第六,60Hz 真的有用。高刷很爽,离电写代码没必要一直开着。

第七,真正费电的东西经常藏在后台:Chromium、Gradle、Kotlin、Waybar、Playwright、watcher 或自动化脚本,哪个持续转,哪个就会吃电。

第八,别为了少注销一次去在线硬拔 NVIDIA 图形栈。稳定比花活重要。

第九,长期插电开机可以,但电池阈值和关屏要做好。

第十,Arch 最有意思的地方就在这里:它一开始不一定照顾你,但你可以把它改到非常贴合自己。

这台幻 16 Air 2025 现在终于褪掉了“游戏本硬装 Linux”的生硬感,开始像一台属于我的 Arch 移动工作站。