Ubuntu 26.04 笔记本功耗排查记录
设备:ThinkPad X1 Extreme Gen 5(i7-12700H + RTX 3060)
系统:Ubuntu 26.04
日期:2026-05-31
耗电情况:1小时电量告罄。
文章目录
[Ubuntu 26.04 笔记本功耗排查记录](#Ubuntu 26.04 笔记本功耗排查记录)
一、起因
二、测量过程
[第一步:尝试 Powertop](#第一步:尝试 Powertop)
[第二步:尝试 NVIDIA 驱动](#第二步:尝试 NVIDIA 驱动)
[第三步:尝试 RAPL(Intel 内置功耗测量)](#第三步:尝试 RAPL(Intel 内置功耗测量))
第四步:写采样脚本
[三、关闭 NVIDIA 独显(关键步骤)](#三、关闭 NVIDIA 独显(关键步骤))
问题:独显一直在耗电
解决方法一:切换到纯集显模式(推荐)
[解决方法二:Runtime PM 自动休眠(不重启)](#解决方法二:Runtime PM 自动休眠(不重启))
实际效果
四、测量结果
重启前(系统运行一段时间,空闲状态)
重启后(刚开机,系统服务启动中)
为什么重启后反而更高?
五、结论
[34W 正常吗?](#34W 正常吗?)
[Powertop 的占比有什么用?](#Powertop 的占比有什么用?)
六、以后怎么快速查看功耗
七、过程中遇到的问题
[问题 1:Powertop 只给占比不给瓦数](#问题 1:Powertop 只给占比不给瓦数)
[问题 2:重启后 NVIDIA 驱动没加载](#问题 2:重启后 NVIDIA 驱动没加载)
[问题 3:RAPL 能量值溢出](#问题 3:RAPL 能量值溢出)
一、起因
想看看系统里什么东西在耗电,方便优化。
之前跑了 Powertop,它给了一个报告,里面有占比(%),比如:
进程
占比
intel_atomic_commit_work
40.2%
Firefox
10.0%
i915_gem_free_work
8.0%
但问题是:占比不等于功耗。40% 是什么意思?是 4W 还是 40W?看不出来。
所以决定用其他方法获取真实瓦数。
二、测量过程
第一步:尝试 Powertop
bash
复制代码
sudo powertop --time=5
结果:只给占比,不给瓦数。放弃。
第二步:尝试 NVIDIA 驱动
bash
复制代码
nvidia-smi --query-gpu=power.draw --format=csv
结果:9.43 W,独显基本空闲。这个能用。
第三步:尝试 RAPL(Intel 内置功耗测量)
bash
复制代码
sudo cat /sys/class/powercap/intel-rapl:0/energy_uj # CPU 整包
结果:只能读到累计能量(微焦耳),不是直接的瓦数。
需要自己算:两次读数相减 ÷ 时间间隔 = 功耗(W)
第四步:写采样脚本
bash
复制代码
#!/bin/bash
E0=$(sudo cat /sys/class/powercap/intel-rapl:0/energy_uj)
E0c=$(sudo cat /sys/class/powercap/intel-rapl:0:0/energy_uj)
E0u=$(sudo cat /sys/class/powercap/intel-rapl:0:1/energy_uj)
E0g=$(sudo cat /sys/class/powercap/intel-rapl:1/energy_uj)
T0=$(date +%s%N)
sleep 3
E1=$(sudo cat /sys/class/powercap/intel-rapl:0/energy_uj)
E1c=$(sudo cat /sys/class/powercap/intel-rapl:0:0/energy_uj)
E1u=$(sudo cat /sys/class/powercap/intel-rapl:0:1/energy_uj)
E1g=$(sudo cat /sys/class/powercap/intel-rapl:1/energy_uj)
T1=$(date +%s%N)
DT=$(( (T1-T0)/1000000 ))
calc() {
local d=$(($2 - $1))
[ $d -lt 0 ] && d=$(( d + 268435456000 ))
echo "scale=1; $d / $DT / 1000" | bc
}
echo "CPU 总包: $(calc $E0 $E1) W"
echo "CPU 核心: $(calc $E0c $E1c) W"
echo "CPU 集显: $(calc $E0u $E1u) W"
echo "独显/其他: $(calc $E0g $E1g) W"
三、关闭 NVIDIA 独显(关键步骤)
问题:独显一直在耗电
重启前测量发现,即使没有运行 3D 程序,NVIDIA RTX 3060 也在耗电(~9W)。
解决方法一:切换到纯集显模式(推荐)
第一步:切换到 Intel 集显
bash
复制代码
sudo prime-select intel
第二步:停止并禁用 nvidia 持久化守护进程
bash
复制代码
sudo systemctl stop nvidia-persistenced
sudo systemctl disable nvidia-persistenced
第三步:重启生效
bash
复制代码
sudo reboot
验证:
bash
复制代码
prime-select query
# 应该输出: intel
nvidia-smi
# 应该报错:找不到 GPU = 关成功了
解决方法二:Runtime PM 自动休眠(不重启)
如果不想重启,可以让系统自动管理独显电源:
查看独显状态:
bash
复制代码
cat /sys/bus/pci/devices/0000:01:00.0/power/runtime_status
# suspended = 已休眠 ✓
# active = 没休眠,要处理
cat /sys/bus/pci/devices/0000:01:00.0/power/control
# auto = 自动管理 ✓
# on = 一直开着,要改成 auto
手动切换为 auto 模式:
bash
复制代码
echo "auto" | sudo tee /sys/bus/pci/devices/0000:01:00.0/power/control
TLP 已配置自动管理:
bash
复制代码
grep RUNTIME_PM /etc/tlp.conf
# RUNTIME_PM_ON_AC=auto
# RUNTIME_PM_ON_BAT=auto
实际效果
方法一(prime-select):重启后独显完全关闭,节省约 9W 功耗
方法二(Runtime PM):独显空闲时自动休眠,节省约 9W 功耗
四、测量结果
重启前(系统运行一段时间,空闲状态)
组件
功耗
CPU 整包
~10 W
NVIDIA RTX 3060
~9 W
合计
~20 W
重启后(刚开机,系统服务启动中)
组件
功耗
CPU 核心
8.7 W
Intel 集显
25.4 W
NVIDIA RTX 3060
已休眠(不耗电)
合计
~34 W
为什么重启后反而更高?
刚重启时,系统服务还在启动(load average: 1.63),CPU 和集显都在干活。等几分钟系统稳定后,功耗会降下来。
五、结论
34W 正常吗?
正常。对比一下:
设备
CPU+GPU 功耗
MacBook Air M2 待机
2-3W
Intel N100 小主机
5-8W
你的 i7-12700H
~34W
游戏本满载
80-150W
i7-12700H 有 14 核 20 线程,光集显驱动屏幕就要 ~25W。这个配置天生比低功耗设备高,不是坏了。
Powertop 的占比有什么用?
占比能告诉你哪个组件相对最耗电 ,但不能告诉你绝对功耗是多少。
比如 Powertop 说 GPU 占 40%,你不知道是 4W 还是 40W。用 RAPL 才能知道真实数字。
六、以后怎么快速查看功耗
bash
复制代码
# 方法一:看累计能量(微焦耳),自己算
sudo cat /sys/class/powercap/intel-rapl:0/energy_uj
# 方法二:看温度(间接判断)
sensors
# 方法三:看 NVIDIA 独显功耗(如果有)
nvidia-smi --query-gpu=power.draw --format=csv
# 方法四:看系统负载(判断是否在忙)
uptime
如果想知道具体瓦数,用上面的 RAPL 脚本跑一下就行。
七、过程中遇到的问题
问题 1:Powertop 只给占比不给瓦数
解决: 用 RAPL 接口读取累计能量,自己算功耗。
问题 2:重启后 NVIDIA 驱动没加载
bash
复制代码
nvidia-smi
# 报错:couldn't communicate with the NVIDIA driver
原因: 刚重启时驱动还没加载完,或者系统用了 nouveau 驱动。
解决: 等一会儿,或者检查驱动:
bash
复制代码
lsmod | grep nvidia
cat /proc/driver/nvidia/version
问题 3:RAPL 能量值溢出
energy_uj 最大约 268435456000(268kJ),超过会归零。
解决: 脚本里加了溢出处理:
bash
复制代码
local d=$(($2 - $1))
[ $d -lt 0 ] && d=$(( d + 268435456000 ))
本账号所有文章均为原创,欢迎转载,请注明文章出处:https://shandianchengzi.blog.csdn.net/article/details/161573293。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。