所有省电技术,都是“占空比游戏”

张开发
2026/4/18 8:33:00 15 分钟阅读

分享文章

所有省电技术,都是“占空比游戏”
从 BLE 广播间隔到 CPU 的 C-State用一个公式解释所有低功耗设计你可能会觉得省电技术五花八门——蓝牙有广播间隔、连接间隔Wi‑Fi 有 PSM 省电模式CPU 有 C1 到 C10 各种睡眠状态操作系统有 Tickless 内核……它们之间有没有共同的本质有。它们都是同一个数学公式的不同变体P_avg P_active × D P_sleep × (1 - D)其中 D T_active / (T_active T_sleep)就是​占空比​——活跃时间占总时间的比例。你想省电就把 D 降下来。但 D 不能无限小因为从睡眠回到活跃需要时间这个时间叫​唤醒延迟​。你愿意等越久功耗就能降得越低。这就是​能量-延迟权衡曲线​。所有低功耗设计都是在这条曲线上找一个合适的点。一、CPU 的 C-State睡眠越深代价越大现代处理器支持多个电源状态C-State数字越大睡得越深唤醒越慢。C-State硬件行为唤醒延迟功耗相对 C0C0执行指令–100%C1 (HLT)停止时钟缓存保留 1µs1-5%C2停止内部时钟几 µs0.5-2%C3关闭 PLL可能 flush L1/L210-50 µs0.1-0.5%C6 及更深核心电压几乎为零缓存写回 LLC100 µs – ms 0.1%每个 C-State 都有一个 ​target_residency​——进入该状态后至少要停留多长时间才能抵消进入/退出的开销。Linux 的 cpuidle governor 会预测下次唤醒的时刻只选择那些 target_residency 小于预测空闲时长的状态。​反直觉事实​如果空闲时间太短进入深睡再醒来的能量开销可能超过浅睡一直等的能量。所以更深的睡眠不一定更省电。二、BLE通过间隔参数精细控制占空比BLE 是专为极低功耗设计的无线协议其省电完全依赖于可编程参数。​广播模式​无连接广播间隔范围20ms ~ 10.24s平均功耗 ≈ 峰值电流 × (广播事件时长 / 间隔)例子峰值 5mA事件 1ms间隔 20ms → 平均 250µA间隔 2s → 平均 2.5µA代价设备被发现的时间 ≈ 广播间隔 × 1.5连接建立变慢。​连接模式​连接间隔范围7.5ms ~ 4s从机在每个连接间隔醒来监听无数据则立即睡去。​从设备延迟​Slave Latency允许从机忽略连续 N 个连接事件而不被断连。例如连接间隔 2s延迟 9 → 从机每 20s 才响应一次平均功耗可降到几 µA。代价主机发起的下行数据最多可能延迟 (延迟 1) × 连接间隔。​一个真实的传感器参数组合​续航一年未连接时广播间隔 2sTX 功率 -20dBm平均电流 5µA连接后空闲连接间隔 4s从延迟 19每 80s 响应一次加上 BLE 控制器的自主保活平均电流 2µA数据上传时临时切换到 15ms 连接间隔延迟降到几十 ms仅持续几百 ms200mAh 的 CR2032 电池可支撑 4-5 年。三、Wi‑Fi 的省电模式PSM和 TWTWi‑Fi 功耗远高于 BLE但通过省电模式可以大幅降低占空比。​传统 ​PSM​Station 在 Beacon 间隔通常 100ms醒来检查 TIM 位是否有数据。无数据则立即睡去。占空比 ≈ 唤醒时间 / 100ms典型平均电流几 mA。延迟代价下行数据最多缓存一个 Beacon 周期。**​Wi​‑​​Fi​ 6 目标唤醒时间TWT**​设备与 AP 协商一个唤醒时刻表比如每 1s 醒 10ms。比传统 PSM 更灵活可将平均功耗降到几百 µA接近 BLE 水平但吞吐量仍受限于唤醒窗口。​硬件保活​现代 Wi‑Fi 芯片可以独立发送空数据包维持连接无需 CPU 干预。这是典型的“将占空比下放到外设”让 CPU 可以安心睡大觉。四、USB 的挂起与选择性挂起USB 是有线总线但省电机制同样体现占空比思想。​挂起​总线空闲超过 3ms设备自动进入挂起状态电流 2.5mA很多设备做到 200µA。恢复时需主机发送唤醒信号或设备远程唤醒延迟约几毫秒。​选择性挂起​OS 可以单独挂起一个空闲的 USB 设备如未使用的鼠标而总线上的其他设备仍然活跃。这允许 USB 控制器进入低功耗 D-State进而释放 CPU 的睡眠约束。​痛点​某些廉价 USB 设备不支持选择性挂起导致整个 USB 控制器无法睡眠从而阻止 CPU 进入深度 C-State。诊断命令lsusb -t查看设备树powertop查看唤醒频率。五、操作系统Tickless 内核消灭周期性唤醒传统 OS 内核有一个固定的时钟中断例如 Linux HZ1000 表示每 1ms 一次。即使系统完全空闲CPU 也会每 1ms 被唤醒一次这相当于强制占空比下限至少 0.1%而且完全无法进入深度 C-State因为空闲时长永远小于 1ms。​Tickless 模式​LinuxCONFIG_NO_HZ_IDLEFreeRTOS 的 Tickless Idle Mode解决了这个问题当所有任务都阻塞时内核停止周期性时钟中断改为设置一个单次定时器到期时间 下一个已知的定时器事件或外设超时。CPU 可以在此期间进入任意深度的 C-State直到该定时器或外部中断唤醒它。​效果​唤醒频率从 1000Hz 降到下一个事件的频率例如 0.1Hz占空比下降几个数量级。​代价​在睡眠期间get_tick()类函数不再递增依赖它的超时逻辑需要特殊处理。六、三个反直觉的启发更深的睡眠不一定更省电如果空闲时间太短进入深度睡眠再醒来的能量开销包括保存/恢复状态、重新锁定 PLL 等可能超过浅睡一直等的能量。这叫“睡眠开销过路费”。最快的计算也可能是最省电的对于突发性任务如传感器数据处理用最高频率快速完成race‑to‑idle然后让 CPU 进入极深睡眠总能耗往往低于降频慢慢跑。因为睡眠时的功耗远低于运行时的功耗。最大的敌人不是功耗是唤醒频率一颗芯片深度睡眠时可能只耗 1µA但如果每 10ms 被唤醒一次哪怕只醒 1ms平均功耗 ≈ 1mA×0.1 1µA×0.9 ≈ 100µA比 1µA 大了 100 倍。所以合并中断、延长轮询​间隔、使用硬件 offload这些减少唤醒次数的技术往往比降低活跃功耗更有效。七、一个可操作的思维框架当你拿到一个带电源管理的系统按这四步走​画出唤醒时间线​记录系统从启动到下一次睡眠之间被哪些事件唤醒中断、定时器、DMA。每个事件标出唤醒时刻、活跃时长、下一次睡眠时刻。​计算当前占空比​D ΣT_active / T_total。目标是把 D 压到 1% 以下对电池供电设备。找出占空比​​的主要贡献者​唤醒次数太多→ 合并中断增大轮询间隔用硬件保活。单次活跃时间太长→ 优化代码或用 race‑to‑idle。某个外设无法睡眠→ 检查驱动是否支持 runtime PM。​**逐层检查“延迟预算”**​从应用层往下问用户/应用能忍受的最大延迟是多少这个延迟能否分配给下层的睡眠下层是否提供了相应深度的睡眠状态如果某层没有提供足够的睡眠深度那就是瓶颈。八、写在最后下次你看到一个低功耗参数比如 BLE 广播间隔 1s或者 CPU 进入 C6 的驻留时间不要再把它当作孤立的数字。把它放进占空比公式里P_avg P_active × D P_sleep × (1 - D)问自己当前 D 是多少延迟预算还有多少哪个外设在频繁唤醒系统当你学会用这个公式审视每一个省电技术你就掌握了系统级能耗优化的​元思维​。本文节选自《权衡之境》主题 21。书稿已完成出版在即。关注「权衡之境」获取新书信息和更多技术哲学文章。——高翔技术哲学作者系统架构师。著有《权衡之境一位工程师的技术哲学笔记》专注技术决策的底层逻辑与思维模型。

更多文章