2011 年 ARM 宣布 big.LITTLE:大核性能高、小核省电,按需切换。2021 年 Intel Alder Lake 把 P-core(Golden Cove)+ E-core(Gracemont)带到桌面。现在手机、平板、笔记本、甚至服务器 CPU 都是异构的。调度器得知道”不同核不等价”。
一、先看图:异构 CPU
flowchart LR
subgraph BIG[大核 · 高性能]
B0[CPU 0<br/>capacity=1024]
B1[CPU 1<br/>capacity=1024]
end
subgraph LITTLE[小核 · 省电]
L0[CPU 2<br/>capacity=430]
L1[CPU 3<br/>capacity=430]
L2[CPU 4<br/>capacity=430]
L3[CPU 5<br/>capacity=430]
end
T1[任务 util=850<br/>misfit on LITTLE] -. migrate .-> BIG
T2[任务 util=200<br/>适配 LITTLE] --> LITTLE
classDef b fill:#388bfd22,stroke:#388bfd,color:#adbac7;
classDef l fill:#3fb95022,stroke:#3fb950,color:#adbac7;
classDef t fill:#f0883e22,stroke:#f0883e,color:#adbac7;
class B0,B1 b
class L0,L1,L2,L3 l
class T1,T2 t
关键:
- 每 CPU 有
capacity值(大核 1024 为基准,小核如 430) - 每任务有
util_avg(PELT 指数平均) util_avg > capacity * threshold→ misfit,应迁大核
二、capacity-aware scheduling
2.1 capacity 从哪来
设备树 / ACPI 表告诉内核每 CPU 的
cpu-capacity。也可以
/sys/devices/system/cpu/cpuX/cpu_capacity
读。
Intel 通过 Thread Director (ITD) 硬件给实时建议——某任务是 “scalar heavy”(适合 E)还是 “vector heavy”(适合 P)。
2.2 util_avg
PELT(见 C-20)追踪每任务对 CPU 的占用率,0-1024 范围。用它估计”这任务迁到小核是否够跑”。
2.3 misfit migration
周期负载均衡里加一步:扫每 CPU,看 running 任务 util 是否 > capacity。有则 misfit,触发专用 migration 把它拉到更大核。
三、Energy-Aware Scheduling (EAS)
不只看能不能跑,还看省不省电。
能量模型(struct em_perf_domain):对每个”频率-功耗”点给一个
(capacity, power) 样本。
调度决策时枚举候选 CPU:
energy_cost = Σ over CPUs (util_after * power_at_that_freq)
选能量最小的 CPU
不走 wake-affine 的纯 cache 启发式,而走能量计算。在移动/笔记本场景下可省 10-30% 电。
开启:CONFIG_ENERGY_MODEL + 设备树注入 OPP
表。Android GKI、ChromeOS 默认开。
四、UCLAMP:用户态提示
sched_util_clamp_min /
sched_util_clamp_max:给任务指定”至少按这个
util 算” 或 “最多按这个 util 算”。
应用:
- 前台应用 boost:clamp_min = 500 → 被调度器认为”它需要 50% 大核”,拉上大核
- 后台同步:clamp_max = 200 → 限制它被放大核
API:
struct sched_attr attr = {
.size = sizeof(attr),
.sched_policy = SCHED_NORMAL,
.sched_flags = SCHED_FLAG_UTIL_CLAMP_MIN,
.sched_util_min = 512,
};
sched_setattr(0, &attr, 0);Android SystemServer 在 foreground app 上加 UCLAMP_MIN boost。
五、Intel Thread Director (ITD)
Alder Lake 以来 Intel CPU 内部有专用 “director”,实时检测每线程属性(整数密集 / 向量密集 / spin-wait),在每 μs 级更新建议。
内核看 IA32_THREAD_FEEDBACK_CHAR_MSR
获取推荐分类。调度器用来:
- 把高 IPC 线程放 P
- spin-wait 放 E(反正吃不到计算)
- AVX 512 绑 P(E core 没 AVX512)
在 Linux 6.0+ 合入基本支持。Windows 11 是首发。
六、HMP 调度决策流
flowchart TB
W[wakeup/tick] --> FEAS[find feasible cpus]
FEAS --> ENE[EAS: 能量最小?]
ENE --> BOOST[UCLAMP min 满足?]
BOOST --> ITD[ITD 建议匹配?]
ITD --> PICK[选中 CPU]
classDef s fill:#3fb95022,stroke:#3fb950,color:#adbac7;
class W,FEAS,ENE,BOOST,ITD,PICK s
策略层从内到外:util → capacity → EAS 能量 → UCLAMP boost → ITD 硬件提示。大部分手机 / 笔记本落在 EAS + UCLAMP 组合。
七、典型失效场景
7.1 小核 CPU-bound 卡
一个计算任务被放小核,misfit 迁移迟迟不到 → 卡顿。
诊断:trace-cmd record -e sched:sched_migrate_task -e sched:sched_stat_runtime
解决:显式 cpuset 绑大核;或 boost
UCLAMP_MIN
7.2 大核过热降频
后果:调度器认为大核 capacity 1024,实际
700。cpufreq_cdev 跟 thermal 联动
/sys/.../cpufreq/scaling_cur_freq。
解决:调优散热;或
cpufreq_set_policy 固定频率
7.3 Android GKI 与厂商差异
Google GKI 提供标准 EAS,但厂商(三星、荣耀、小米)普遍有自定义 OEM 调度器(WALT、SchedTune 旧版、米家”涡轮”)。效果不一。
7.4 服务器 P+E
Xeon 的混合架构(Sierra Forest E-core Xeon)出现后,服务器调度器需处理异构。大多数服务器软件还没”感知” E 核;常见做法是用 cpuset 完全隔离、不靠自动。
八、诊断
cat /sys/devices/system/cpu/cpu0/cpu_capacity
# 1024
cat /sys/devices/system/cpu/cpu4/cpu_capacity
# 430
cat /proc/<pid>/sched | grep util
# se.avg.util_avg : ...
cat /sys/fs/cgroup/foo/cpu.uclamp.min
perf sched timehist、bpftrace sched:*
追 placement 决策。
九、开发者建议
- 普通应用不需要管——内核默认已很智能
- 前台 UI / 游戏:UCLAMP_MIN 500+ boost
- 后台任务:UCLAMP_MAX 限制,或 SCHED_IDLE
- 专用线程池:cpuset 绑大/小核
- 避免自旋等待:E 核浪费功耗,P 核抢占敏感;用 futex + 睡眠
十、未来方向
- CPU hotplug + idle injection:把整颗大核离线省电
- GPU/NPU 调度一体化:AI 负载在 CPU/GPU/NPU 间自动选
- cache/memory bandwidth aware scheduling:RDT / MPAM 的进一步整合
- task-group 级 UCLAMP:cgroup v2 支持逐步完善
十一、小结
- 异构 CPU 要求 capacity + util + 能量模型联动
- EAS 是手机/笔记本的主力
- UCLAMP 给用户态 hint;Android 重度使用
- Intel Thread Director 把硬件观测带进来
- 服务器 P+E 场景还在起步
下一篇 C-26 讲调度延迟分析——怎样证明”延迟是不是调度器的锅”。
参考文献
- ARM “big.LITTLE Technology” 白皮书
- Intel “Hybrid Technology – Performance + Efficient Cores” 白皮书 (2021)
Documentation/scheduler/sched-energy.rst- Pelosi, D. et al. “EAS: Energy-Aware Scheduling for Linux.” ELC-Europe 2018
- Corbet, J. “Util clamp” 系列 LWN.net 2018-2020
- Corbet, J. “Intel Thread Director and Linux.” LWN.net 2022
工具
lscpu -e=CPU,MAXMHZcpupower frequency-infobpftrace -e 'tracepoint:sched:sched_migrate_task { ... }'perf sched、schedviz- Android
systrace/perfetto
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【操作系统百科】内存回收
Linux 内存回收是 VM 最复杂的子系统之一。本文讲 active/inactive LRU、kswapd 与 direct reclaim、watermark 三线、swappiness 的真实含义、MGLRU 改造、memcg 回收与 PSI。
【操作系统百科】交换
swap 还值得开吗?本文讲 swap area 基础、swap cache、zram 压缩内存、zswap 前端压缩池、swappiness 的真实含义、容器里的 swap 策略,以及为什么现代 Android 全靠 zram 不靠磁盘。
【操作系统百科】Slab/SLUB 分配器
buddy 只管页粒度(4K+),内核大多数对象只有几十到几百字节。slab/SLUB 在 buddy 之上做对象级缓存。本文讲 slab 历史、SLUB 接手、SLOB 退场、kmem_cache、per-CPU cache、KASAN 集成。
【操作系统百科】用户态分配器
glibc malloc、tcmalloc、jemalloc、mimalloc 各有哲学。本文讲 arena、thread cache、size class、madvise 返还策略、碎片与 RSS 膨胀、如何根据负载选分配器。