凯哥stack

打造极致省电的Linux Book

说明

荣耀MagicBook Pro Linux版,到手后换为Ubuntu桌面版,唯一不足是功耗略高,准备折腾一下。

笔记本硬件信息:

  • CPU: i7-8565U
  • Memory: 8G
  • GPU: Intel i915集成 + Nvidia MX250(可以运行CUDA)
  • Disk: 512G Nvme SSD

主要在闲时写个文档的功耗都有10W(可以通过upower -d命令查看),降低功耗的手段基本是两大手段,一个是CPU,一个是显卡(该本本带独立显卡),显示器可以调节亮度。

折腾显卡

Ubuntu安装好,并安装Nvidia驱动,系统默认不启用独立显卡(MX250),按照Nvidia的说法,需要在启动时禁用nouveau驱动,由于本人有时会玩一玩CUDA,因此要启用Nvidia显卡,按照说明禁用nouveau。

创建/etc/modprobe.d/blacklist-nvidia-nouveau.conf文件,内容如下:

1
2
blacklist nouveau
options nouveau modeset=0

重启电脑生效。

该场景下,功耗大概10来瓦,多个显卡可以勉强接受。然而在一次Ubuntu升级后,出现的问题让我觉得可以值得研究,Ubuntu升级后,内核版本更新,这样会导致Nvidia的驱动不可用,顺便多说一句Nvidia的显卡驱动是不开源的(曾被Linus吐槽过,链接),因此在驱动安装过程中,会检查系统中Nvidia的ko文件是否存在或者与内核匹配,如果不匹配会进行编译安装,因此如果内核升级后,一定要重新安装一次Nvidia的驱动,否则显卡不可用。

由于升级内核后,我并未重新安装Nvidia的驱动,因此独立显卡失效,桌面切换到intel的集成显卡,但是功耗并没有降,这很奇怪,于是查看Nvidia的状态发现,居然是在线耗电状态!!!

查看方法:

1
2
3
4
5
6
7
8
# lspci
02:00.0 3D controller: NVIDIA Corporation Device 1d13 (rev a1)
# Nvidia graphic card,记录前面的ID,下面的命令中devices通过ID区分

# cat /sys/bus/pci/devices/0000\:02\:00.0/power/runtime_status
active # 在线
# cat /sys/bus/pci/devices/0000\:02\:00.0/power/runtime_usage
2 # 大于0,表示正在耗电

经过不断折腾(此处略去几千字),要想关闭独立显卡有几个方法;

  • 简单粗暴法
1
2
3
4
5
# 在系统中对Nvidia显卡下电,显卡直接在系统中消失
# echo "1" > /sys/bus/pci/devices/0000\:02\:00.0/remove

# 显卡自动挂起,推荐
# echo "auto" > /sys/bus/pci/devices/0000\:02\:00.0/power/control
  • 启用nouveau

nouveau为开源的Nvidia,非官方,因此支持的功能有限,不支持CUDA等,该驱动与Nvidia的驱动互斥,加载该驱动后,Nvidia的驱动不会被加载,系统不启用Nvidia,最后nouveau发现显卡空闲,将显卡挂起,也可以达到省电的目的,方法参考前面提到的,注释掉/etc/modprobe.d/blacklist-nvidia-nouveau.conf内容即可,系统为何没有启动nouvean驱动的显卡呢,主要是Nvidia驱动在在X启动前加了一个步骤是gpu-manager,由它来选择使用哪个显卡,参考配置/etc/systemd/system/display-manager.service.wants/gpu-manager.service。

  • 我喜欢的方式

关闭nouveau,关闭nvidia(需要将nvidia的驱动从kernel modules中移走,否则gpu-manager会自动加载)

1
2
mkdir nvidia_driver_bkup
mv /lib/modules/$(uname -r)/kernel/drivers/video/nvidia* nvidia_driver_bkup

在系统启动的rc.local中设置nvidia的电源模式为auto,这样显卡自动挂起

1
2
# /etc/rc.local
echo "auto" > /sys/bus/pci/devices/0000:02:00.0/power/control

折腾CPU

众所周知,整个Linux的电源管理通过ACPI完成,ACPI对系统所有设备进行电源管理设置,CPU的电源管理也在ACPI的管理范围,另外Intel内置了CPU调频的机制在里面,默认可以通过cat /proc/cpuinfo来查看,CPU的频率是变化的,以最低700M到最高频率之间不断变化,降频可以省电。

另外注意到Intel有另外一款DPTF(Dynamic Platform and Thermal Framework)的功能,该功能在Chromimum OS开发用于动态调整CPU的运行,同时也支持Ubuntu系统,但发现当前的版本还是跟不上硬件更新,很多thermel不支持,比如在我的本本中可以支持的thermel是passive2、critical、adaptive-performace三种模式,但是在最新的DPTF中值支持passive1、active、critical三种,因此想用passive模式无法使用。

于是自己写了一个简易程序可以手动设置当前的thermel为passive2,代码参考

不幸的是,该优化在我的本本上没有起到降功耗的效果,应该是与ACPI的调节类同。

总结与收获

独立显卡灵活配置

  1. 备份nvidia驱动
1
2
mkdir nvidia_driver_bkup
mv /lib/modules/$(uname -r)/kernel/drivers/video/nvidia* nvidia_driver_bkup
  1. 关闭nouveau、nvidia驱动自动加载

将以下内容写入文件/etc/modprobe.d/blacklist-nvidia-nouveau.conf

1
2
3
blacklist nouveau
options nouveau modeset=0
blacklist nvidia
  1. 启动设置nvidia电源管理为auto

将以下写入/etc/rc.local,注意device ID通过lspci查看,并替换

1
2
#!/bin/bash
echo "auto" > /sys/bus/pci/devices/0000:02:00.0/power/control

完整配置脚本

临时启用nvidia显卡

  1. 将备份的nvidia内核驱动还原
1
mv nvidia_driver_bkup/nvidia* /lib/modules/$(uname -r)/kernel/drivers/video/
  1. 加载驱动
1
modprobe nvidia

如果想下次启动使用nvidia驱动,只需要按照第一步,将nvidia的驱动文件还原即可,这样下次启动会自动加载nvidia驱动,如果不想在下次启动加载,一定要将nvidia的内核驱动文件移走。

其他

能否关闭intel集成显卡,独立使用Nvidia显卡?这里又发现一个秘密,在启用Nvidia显卡启动后,曾尝试对Intel的i915下电操作,操作后整个显示器熄屏无显示,无法唤醒,只能重启机器。通过gpu-manager的日志终于找到了原因,原来,显示器是与Intel集成显卡连接,Nvidia与集成显卡连接,关闭集成显卡,Nvidia与显示器之间连接断开了。

整个折腾过程通过关闭独立显卡可以将功耗降到3瓦左右,同时又可以随时启用Nvidia来玩一玩CUDA已经基本满足折腾的诉求了。

凯哥stack

著作权归作者所有,禁止转载


专题:

本文发表于 2020-06-13,最后修改于 2020-06-14。

本站永久域名kaige86.com,也可搜索「 凯哥stack 」找到我。

期待关注我的 ,查看最近的文章和动态。


上一篇 « 计算机体系结构(二) Code As Data ? Data As Code ?

推荐阅读

Big Image