土法炼钢兴趣小组的算法知识备份

【操作系统百科】idle governors:空闲管理的艺术

文章导航

分类入口
os
标签入口
#cpuidle#c-states#menu-governor#teo-governor#idle-inject#uncore-idle

目录

CPU 空闲本身是个决策问题:该进哪个 idle state 睡?深睡省电但唤醒慢;浅睡反应快但耗。选错了影响功耗甚至响应延迟。Linux 把这块抽成 cpuidle 子系统,governor 插件决定”睡多深”。

一、先看图

flowchart LR
    CPU[CPU idle loop] --> G{cpuidle governor}
    G -->|menu / teo 决策| S0[C0 running]
    G --> C1[C1 halt<br/>~1μs]
    G --> C2[C2<br/>~10μs]
    G --> C3[C3<br/>~50μs]
    G --> C6[C6<br/>~200μs 关 core]
    G --> C7[C8/C10<br/>关 package/uncore]
    S0 -.事件唤醒.-> WK[wake → 恢复]
    C1 -.-> WK
    C6 -.-> WK
    classDef low fill:#3fb95022,stroke:#3fb950,color:#adbac7;
    classDef mid fill:#388bfd22,stroke:#388bfd,color:#adbac7;
    classDef deep fill:#a371f722,stroke:#a371f7,color:#adbac7;
    class S0,C1 low
    class C2,C3 mid
    class C6,C7 deep

C-state 越大:功耗越低、退出延迟越大。choice 权衡”预期 idle 时间”。

二、cpuidle 架构

三个模块:

/sys/devices/system/cpu/cpu0/cpuidle/state0..N/

name           # POLL / C1 / C1E / C6 / ...
desc
latency        # us
residency      # us, minimum time in this state to be worth it
usage          # 进入次数
time           # 累计停留 μs

三、governor 演进

3.1 ladder

老 governor,单调上 / 下一级。简单,在多数服务器过时。

从 3.x 到现在长期默认。预测下次 idle 时长基于:

选择 target_residency < predicted 的最深状态。

痛点:对突发不规则唤醒不敏感;某些负载省电不够。

3.3 teo(Timer Events Oriented)

5.1+ 引入,现代默认候选。思路更单纯:“相信 timer 预测”。统计每个 C-state 的 命中率(实际停留时间 >= target_residency 的比例)。进入前选命中率 > 50% 且延迟最深的。

TEO 在交互 / 服务器混合负载上表现更稳定。Fedora、Ubuntu 较新版本默认 teo(/sys/devices/system/cpu/cpuidle/current_governor_ro)。

3.4 haltpoll

专为 KVM guest 设计:先 busy-poll 一会儿(halt-polling),若无事件再真正 halt。降低虚拟机空闲-唤醒延迟。

四、C-state 能耗地图(Intel 参考)

服务器通常不进 PC10(影响 I/O 延迟);笔记本 PC10 很激进。

ARM 类似:WFI(Wait For Interrupt)对应 C1;更深的 cluster idle 关 L2。

五、uncore idle

core 停了还有 uncore(L3、memory controller、PCIe)。Intel “Uncore Frequency Scaling”、AMD 的 CCX 独立时钟。Linux 通过 intel_uncore_frequency 驱动暴露。

影响:

六、idle_inject 与 power capping

主动注入 idle 做温控:intel_powerclamp 把多个 CPU 按比例 idle 注入,达到 TDP / RAPL 限制。云服务商在密集服务器里用它防过热。

也有 cpuidle_haltpoll 与 KVM 的配合。

七、诊断

cpupower idle-info
# 列 governor、每 CPU 可用状态、统计

turbostat --quiet --interval 1
# 看 PkgWatt、CoreC6%、PkgC6%

perf stat -e power/energy-cores/ (RAPL event)看 CPU 能耗。

bpftrace kprobe cpuidle_enter_state 看决策分布。

八、调优场景

8.1 低延迟网络服务

关深 C-state:

intel_idle.max_cstate=1 processor.max_cstate=1
# 或运行时
echo 1 > /sys/devices/system/cpu/cpu0/cpuidle/state3/disable

代价:空闲时功耗 +30-50%。

8.2 电池续航

默认 teo + P-state schedutil。Android 额外有 WALT / 自家 governor。

8.3 实时 (PREEMPT_RT)

限 C-state 最多到 C1;开 idle=poll 把空闲变 busy wait(最保延迟但爆功耗)。

8.4 虚拟化

guest:haltpoll governor;host:cpuidle + kvm.halt_poll_ns 调 polling window。

九、idle 的 tickless 搭档

nohz_full=N:指定 CPU 上完全不收 timer tick。idle 不被唤醒;但需关闭很多 kernel housekeeping。

配合 isolcpus + rcu_nocbs 用:专用 CPU 全时间用户态跑,连 1kHz tick 都没有。HPC / 网络转发面典型配置。

十、常见 bug

bug A:网络延迟 p99 飙几 ms 原因:CPU 进深 C-state,唤醒慢 解决:关深 state 或 cpu-dma-latency PM QoS

bug B:turbostat 显示 PC6 0%,功耗高 原因:某个 I/O / timer 阻止 uncore 进 PC;检查 /sys/kernel/debug/pm_genpd/turbostatPkgWatt

bug C:guest 下延迟高 解决:换 haltpoll governor;调低 halt_poll_ns 或固定 CPU

bug D:AMD Ryzen idle 降频过激 解决:换 cpupower frequency-set -g performance 或 amd_pstate

十一、小结

下一篇 C-28(本子系列收尾)讲 cpufreq governor——频率调节,从 ondemand 到 schedutil 的演进。


参考文献

工具


上一篇调度延迟分析 下一篇cpufreq governor:频率调节

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-04-27 · os

【操作系统百科】内存回收

Linux 内存回收是 VM 最复杂的子系统之一。本文讲 active/inactive LRU、kswapd 与 direct reclaim、watermark 三线、swappiness 的真实含义、MGLRU 改造、memcg 回收与 PSI。

2026-04-28 · os

【操作系统百科】交换

swap 还值得开吗?本文讲 swap area 基础、swap cache、zram 压缩内存、zswap 前端压缩池、swappiness 的真实含义、容器里的 swap 策略,以及为什么现代 Android 全靠 zram 不靠磁盘。

2026-05-03 · os

【操作系统百科】Slab/SLUB 分配器

buddy 只管页粒度(4K+),内核大多数对象只有几十到几百字节。slab/SLUB 在 buddy 之上做对象级缓存。本文讲 slab 历史、SLUB 接手、SLOB 退场、kmem_cache、per-CPU cache、KASAN 集成。

2026-05-07 · os

【操作系统百科】用户态分配器

glibc malloc、tcmalloc、jemalloc、mimalloc 各有哲学。本文讲 arena、thread cache、size class、madvise 返还策略、碎片与 RSS 膨胀、如何根据负载选分配器。


By .