Skip to content

第一百五十一章:电源管理

合道期

涉及内核源码:

林小源走出钟楼,面前出现了一片幽暗的区域。这里的设备大多处于低功耗状态——光幕暗淡,传送带缓慢,处理器核心只有一盏微弱的指示灯在闪烁。

一个穿着黑色斗篷的身影从阴影中走出。他的斗篷上绣着一颗电池的图案,电池的电量只剩最后一格。

"我是电源管理。"他的声音低沉而平静,"我的工作是让系统在空闲时尽可能少地消耗能量。"

他抬起手,指向远处的一排设备。那些设备正在逐一熄灭——指示灯从亮变暗,风扇从快变慢,最终完全静止。

"这就是 suspend-to-RAM——内存休眠。"电源管理说,"设备状态保存到内存里,CPU 停止,只有内存还在通电维持数据。整个系统的功耗降到最低。"

林小源感到周围的温度在下降——设备关闭后,热量的来源减少了。空气中弥漫着一种寂静,像是整个世界都屏住了呼吸。

"如果内存也断电了呢?"林小源问。

"那就是 suspend-to-disk——磁盘休眠。"电源管理走到一面石壁前,石壁上刻着休眠流程图,"状态保存到磁盘,然后彻底断电。唤醒时从磁盘恢复——像是一场漫长的冬眠后醒来。"

林小源看着那些逐一熄灭的设备,心想:让系统该睡就睡,也是一门本事。


c
/*
 * 电源管理:
 *
 * 1. 系统休眠 (suspend)
 *    内存休眠 (suspend-to-RAM)
 *    磁盘休眠 (suspend-to-disk)
 *
 * 2. 设备电源管理
 *    runtime PM — 设备级电源管理
 *    设备空闲时自动关闭
 *
 * 3. CPU 频率调节
 *    cpufreq — 动态调整 CPU 频率
 *    空闲时降频省电
 *
 * 休眠流程:
 *   冻结进程 → 设备挂起 → CPU 停止 → 保存状态
 *   唤醒: 恢复状态 → CPU 启动 → 设备恢复 → 解冻进程
 */

printf("=== 电源管理 — 节能的机制 ===\n\n");

printf("电源管理:\n\n");

printf("1. 系统休眠:\n");
printf("   suspend-to-RAM (内存休眠)\n");
printf("   suspend-to-disk (磁盘休眠)\n\n");

printf("2. 设备电源管理:\n");
printf("   runtime PM\n");
printf("   设备空闲时自动关闭\n\n");

printf("3. CPU 频率调节:\n");
printf("   cpufreq\n");
printf("   动态调整 CPU 频率\n\n");

printf("--- 休眠流程 ---\n");
printf("休眠:\n");
printf("  冻结进程\n");
printf("  → 设备挂起\n");
printf("  → CPU 停止\n");
printf("  → 保存状态\n\n");
printf("唤醒:\n");
printf("  恢复状态\n");
printf("  → CPU 启动\n");
printf("  → 设备恢复\n");
printf("  → 解冻进程\n\n");

printf("--- runtime PM ---\n");
printf("设备级电源管理:\n");
printf("  设备空闲时自动关闭\n");
printf("  使用时自动开启\n\n");
printf("pm_runtime_get_sync(dev):\n");
printf("  增加引用计数\n");
printf("  如果设备关闭则开启\n\n");
printf("pm_runtime_put(dev):\n");
printf("  减少引用计数\n");
printf("  如果计数为零则关闭\n\n");

printf("--- cpufreq ---\n");
printf("动态调整 CPU 频率:\n");
printf("  空闲时降频省电\n");
printf("  负载高时升频\n\n");
printf("查看:\n");
printf("  cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq\n");

林小源跟随电源管理走进了设备区域的内部。一个网卡设备正在发送数据——它的指示灯亮着,功耗较高。但当最后一个数据包发出后,指示灯开始闪烁,然后渐渐暗了下去。

"这是 runtime PM,"电源管理说,"设备有自己的电源状态。当它不再被使用时,引用计数降为零,我会自动把它关闭。下次有人要用它时,再自动唤醒。"

林小源看到网卡上有一个小小的计数器。每有一个驱动在使用它,计数器加一;用完了,计数器减一。当计数器归零的那一刻,网卡的电源被切断,整个设备沉入了睡眠。

"如果一个驱动忘了释放引用呢?"林小源问。

电源管理的表情变得严肃:"那设备就永远不会关闭——白白浪费电。这就是为什么驱动必须在用完设备后调用 pm_runtime_put()。引用计数是 runtime PM 的核心——多一个引用就多一份责任。"

林小源看到远处有一个 USB 控制器,它的引用计数在不断跳动——有设备连接时上升,设备断开时下降。控制器的功耗随着计数器的变化而起伏,像是一颗有节律跳动的心脏。

"runtime PM 的好处是不需要用户干预,"电源管理说,"你插入 U 盘,控制器自动唤醒;拔出 U 盘,控制器自动睡眠。一切都是自动的。"

他算是看明白了,runtime PM 的精髓就是自动化——不用人为干预,设备自己知道什么时候该睡、什么时候该醒。

在设备区域的尽头,林小源看到了 CPU 频率调节的控制台。控制台上有几个巨大的旋钮,每个旋钮对应一个 CPU 核心。旋钮的刻度从最低频率到最高频率,当前指针的位置随着 CPU 的负载在实时变化。

"这是 cpufreq。"电源管理走到一个旋钮旁,轻轻转动它。对应的 CPU 核心立刻从低频切到高频,风扇转速也跟着上升。

"负载低的时候,CPU 降频省电。负载高的时候,CPU 升频保性能。"电源管理松开旋钮,让它自己回弹,"但频率切换不是免费的——有延迟,有功耗波动。所以 cpufreq 有多种调度策略:ondemand 看负载即时调整,conservative 温和调整,performance 始终最高频,powersave 始终最低频。"

林小源看着旋钮上的指针在低频和高频之间来回摆动。当他模拟高负载时,指针猛地上升,CPU 核心发出低沉的轰鸣;当他停止负载时,指针缓慢回落,轰鸣声渐渐消失。

"平衡——这就是电源管理的本质。"电源管理说,"你不能让系统一直满负荷运转,也不能让它在需要性能时还省电。找到那个平衡点,就是我的工作。"

林小源低头看了看自己手中的灵力——如果把灵力比作电力,那修炼者也需要在消耗和恢复之间找到平衡。这道理,修仙界和内核世界是一样的。

电源管理的本质就是动态平衡——不能一直满负荷跑,也不能在需要性能时还省电。


道藏笔记

内核启示

电源管理干的事说白了就一句话:不用的时候省着点。系统级的休眠分两种,suspend-to-RAM 把状态存内存、CPU 停机,只剩内存通电;suspend-to-disk 更彻底,状态存磁盘后彻底断电。设备级的 runtime PM 更精细——每个设备有自己的引用计数,没人用就自动断电,有人用就自动唤醒,插个 U 盘控制器自动醒来,拔掉又自动睡去。CPU 频率调节是另一招,负载低时降频省电,负载高时升频保性能。ondemand 看负载即时调整,conservative 温和调整,performance 和 powersave 走极端。这些机制加在一起,就是让系统在性能和功耗之间找到那个最合适的平衡点。


破关试炼

电源管理之试

设备空闲时自动关闭、使用时自动唤醒的设备级电源管理机制叫什么?

答对后才能继续滑动和进入下一章。

以修仙之名,悟内核之道