1. 课程导入

在移动端体验竞争日益激烈的今天,用户对手机的要求早已不只是“跑得快”,而是“又快又省电、还不烫手”。Android 系统的 CPU 调度与功耗优化,正是连接性能与续航的关键工程领域。它既涉及 Linux 内核调度器、CPU 频率与电压调节(DVFS)、大小核拓扑(big.LITTLE / DynamIQ),也涉及 Android 框架层的调度策略、功耗模型与温控机制。本课程的目标,是帮助你把零散的知识点串成一条可落地的工程链路:从理解调度原理,到读懂功耗数据,再到定位卡顿与发热问题,最终能设计并验证优化方案。

一、学习目标:从“看得懂”到“调得动”

本课程不是单纯的内核源码分析课,也不是只讲工具使用的操作课,而是面向 Android 系统性能与功耗工程师的实战课程。学完之后,你应当具备以下能力:

  • 概念清晰:能准确区分调度延迟、调度抖动、CPU 占用率、频率驻留、功耗墙、热墙等核心指标,理解它们之间的因果关系。
  • 框架贯通:能说清从应用线程、Android 调度策略、内核 CFS/EEVDF、cpufreq governor 到 CPU 硬件 P-state 的完整路径。
  • 工具熟练:能使用 systrace/Perfetto、simpleperf、ftrace、cpufreq stats、powermonitor 等工具采集并解读数据。
  • 优化落地:能针对卡顿、掉帧、待机耗电、游戏发热等典型场景,提出可验证的调度与功耗优化方案。
  • 复盘闭环:能建立“指标定义—数据采集—假设验证—回归测试”的工程闭环,避免凭感觉调参。
核心判断:CPU 调度优化的第一原则不是“让 CPU 跑满”,而是“在正确的时间,用正确的核,跑正确的频率”。功耗优化的第一原则也不是“降频省电”,而是“减少无效唤醒与无效算力”。

二、核心概念:调度与功耗的四个基本维度

要理解 Android CPU 调度与功耗优化,先要抓住四个基本维度:任务、CPU、频率/电压、温度/功耗。任务有优先级、亲和性、唤醒频率和运行时长;CPU 有大小核、容量(capacity)、算力差异和 idle 状态;频率与电压决定单位时间的算力与能耗;温度与功耗则反过来限制频率和核的可用范围。四者相互制约,任何单点优化都可能引发连锁反应。

例如,把游戏线程绑到大核并拉高频率,短期帧率会提升,但功耗和温度上升后,热控会触发降频,反而导致更严重的卡顿。因此,调度与功耗必须联合建模,而不是分开处理。

三、整体知识框架:从应用到硬件的五层结构

下图展示了本课程的整体知识框架。它按“应用与框架层 → 调度策略层 → 内核调度器 → 频率与功耗控制 → 硬件与热约束”五层展开,并标出每层的关键对象与观测点。你可以把它当作后续章节的地图:遇到问题时,先判断问题落在哪一层,再选择对应的工具和优化手段。

Android CPU调度与功耗优化知识框架 五层结构 · 从应用任务到硬件热约束 ① 应用与框架层 App 线程 / Binder / Handler / RenderThread / SurfaceFlinger / AMS·WMS 调度提示 观测点:主线程耗时、帧率、Binder 阻塞、线程优先级 ② 调度策略层 cgroup / schedtune / uclamp / 优先级继承 / 前台·后台分组 / 厂商调度策略 观测点:任务分组、boost 值、uclamp min/max、调度延迟 ③ 内核调度器 CFS / EEVDF / RT / DL / 负载跟踪 PELT / 唤醒迁移 / 负载均衡 / 大小核放置 观测点:runqueue 延迟、迁移次数、CPU 容量、任务 util ④ 频率与功耗控制 cpufreq governor / schedutil / DVFS / CPU idle / EAS 能量模型 / 功耗预算 观测点:频率驻留、电压、idle 状态、能量开销、功耗曲线 ⑤ 硬件与热约束 big.LITTLE / DynamIQ / 温度传感器 / 热控策略 / 功耗墙 / 电池与充电约束 观测点:结温、降频点、热控触发、整机功耗 热/功耗反馈限制频率与核选择

四、工程实践路线:从采集到验证的闭环

知识框架解决“知道在哪”,工程路线解决“怎么动手”。建议按以下五步推进,每一步都要求有数据支撑:

  1. 定义问题与指标:明确是卡顿、掉帧、待机耗电还是发热降频,并选定可量化指标,如 99 分位帧耗时、CPU 总功耗、大核驻留比。
  2. 采集数据:用 Perfetto 抓取调度与频率轨迹,用 simpleperf 定位热点函数,用 cpufreq stats 查看频率分布。
  3. 建立假设:例如“主线程被小核拖慢”或“后台唤醒导致无法进入深 idle”。
  4. 实施优化:调整线程优先级、uclamp、cgroup 分组、governor 参数或任务亲和性。
  5. 回归验证:在相同场景下复测指标,确认收益且无副作用,再固化配置。
# 示例:查看 CPU 频率驻留与调度统计
adb shell cat /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state
adb shell cat /proc/schedstat
adb shell dumpsys thermalservice

# 示例:Perfetto 抓取调度与频率轨迹
adb shell perfetto -o /data/misc/perfetto-traces/trace.pftrace \
  -t 10s sched freq idle am wm

五、典型场景与常见误区

以“游戏帧率波动”为例:表面看是 GPU 问题,实际可能是大核被热控降频后,渲染线程调度延迟增大。此时若只调 GPU 参数,往往无效。正确做法是联合查看 CPU 频率、任务迁移和温度曲线,判断是“算力不足”还是“热约束导致的算力波动”。

常见误区 问题本质 正确做法
只看 CPU 占用率 占用率高不等于算力有效,可能大量时间在等锁或迁移 结合 runqueue 延迟、迁移次数、频率驻留综合判断
盲目拉高频率 功耗与温度上升,触发热控后反而降频 先减少无效唤醒与无效算力,再按需 boost
忽略大小核差异 小核跑重任务导致长尾延迟 用 uclamp/亲和性把关键线程放到合适容量核
只优化前台 后台唤醒持续占用 CPU,待机功耗高 用 cgroup 限制后台,减少定时器与广播唤醒
不要在没有基线数据的情况下调参。任何调度或功耗改动,都必须有“改动前—改动后”的对比数据,否则无法判断收益是否真实,也无法排除场景波动带来的误判。

本课程后续将沿着上述五层框架逐层展开:先讲清调度器与负载跟踪,再讲频率与功耗控制,然后进入工具链与实战案例,最后落到卡顿、待机、游戏、热控等典型场景的优化与复盘。你现在需要建立的,是一张“从任务到温度”的完整地图,以及一套“用数据说话”的工程习惯。