cpuidle 是什么
cpuidle 子系统决定 CPU 空闲时进入哪一级 C-state:状态越深越省电,但退出所需时间(latency)越长,唤醒后的响应也越慢。选择由 governor 完成,现代内核常见 menu 与 teo 两种启发式策略,较老平台还有 ladder;同时系统可以用 PM QoS 之类的延迟约束限制允许进入的最大深度。延迟敏感业务与省电需求在这一点上直接冲突,调优前要先明确目标。
基本信息
| 查看命令 | cpupower idle-info(列出 governor 与各状态) |
|---|---|
| sysfs 路径 | /sys/devices/system/cpu/cpu<N>/cpuidle/state*/ |
| governor 文件 | /sys/devices/system/cpu/cpuidle/current_governor |
| 状态属性 | name、desc、latency(微秒)、residency、usage、time |
| 约束手段 | PM QoS 延迟请求(如 /dev/cpu_dma_latency)或驱动请求 |
| 生效范围 | 通常逐 CPU;深睡的启用/禁用可用 cpupower idle-set 调整 |
典型使用场景
- 延迟敏感服务:确认为什么等待唤醒的时间偏长,必要时限制过深的 C-state
- 省电评估:检查空闲时是否真的进入深睡(看 usage/time 增量而非瞬时值)
- 排查「空闲机器功耗仍高」:往往是被频繁中断唤醒只进浅睡,需要从中断源入手
- 与 cyclictest 配合:量化限制 C-state 前后最坏延迟的变化
- 虚拟化环境判断:确认 guest 内看到的 C-state 是否具有参考意义
查看与限制
查看与限制
cpupower idle-info | head -20 # 看当前 governor、可用状态与各自延迟
cat /sys/devices/system/cpu/cpuidle/current_governor # 当前使用的 governor
for d in /sys/devices/system/cpu/cpu0/cpuidle/state*; do echo "$d $(cat $d/name) lat=$(cat $d/latency) use=$(cat $d/usage)"; done
cat /sys/devices/system/cpu/cpu0/cpuidle/state1/usage # 单独读某级使用计数,两次采样对比增长
sudo cpupower idle-set -d 3 # 禁用较深的一级(编号以 idle-info 输出为准)
sudo turbostat --interval 2 # 输出含各 C-state 驻留列(列名随版本不同),用于验证效果状态属性读法
| 文件 | 含义 | 判读要点 |
|---|---|---|
| name | 状态名称,如 POLL、C1、C1E、C6 | 编号越深通常越省电、退出越慢 |
| latency | 退出该状态的延迟(微秒) | 是该状态的属性值,不等于实测延迟 |
| residency | 建议的最短停留时间(微秒) | 停留短于它反而得不偿失 |
| usage | 进入该状态的累计次数 | 看两次采样的增量 |
| time | 在该状态停留的累计时间 | 与 usage 一起判断深睡是否真的发生 |
governor 不只看空闲时长,还看唤醒频率:频繁的定时器与网络中断会让它只选浅睡。因此「空闲功耗高」的根因常在中断源或定时器精度上,禁用深睡只是掩盖现象。
虚拟机里的 C-state 一般由宿主机管理,guest 中读到的层级与计数往往不反映真实硬件行为;评估功耗或最坏延迟应在裸机上测量。