3. CPU性能调优:CPU频率与调度策略、大小核架构优化、负载均衡
好,咱们进入第三章。这一章聊的是CPU调优,说白了就是让芯片的“大脑”跑得更聪明。不是一味地跑得快,而是该快的时候快,该省电的时候省电。我在联发科调过不少项目,这块坑不少,咱们一个一个说。
3.1 CPU频率与调度策略:别让CPU傻跑
CPU频率控制,是性能调优最直接的手段。但很多人一上来就“拉满频率”,这其实是个误区。你想想看,一个App只是滑动列表,你让大核跑2.8GHz,除了发热和耗电,用户体验并不会有提升。
我个人习惯,先看场景。联发科的平台里,CPU调频主要通过 cpufreq 框架。核心是这几个governor:
| Governor | 特点 | 适用场景 |
|---|---|---|
| performance | 一直最高频,性能最强 | 跑分、游戏加载 |
| powersave | 一直最低频,最省电 | 待机、后台任务 |
| ondemand | 负载上来才升频,有延迟 | 老平台兼容 |
| interactive | 根据负载预测调频,响应快 | 日常滑动、轻交互 |
| schedutil | 基于调度器负载,更精准 | 大小核架构首选 |
我在项目中遇到过,某款手机刷微博时发热严重。查了一圈,发现用的是 performance governor。改成 schedutil 后,温度降了5度,流畅度几乎没变。嗯,这里要注意,schedutil 需要内核支持,联发科新平台基本都默认开了。
核心原则:频率跟着负载走,别让CPU“空转高频”。
3.2 大小核架构优化:把活分给对的人
联发科的大小核架构,比如天玑系列的“1+3+4”或“4+4”,不是摆设。大核(Cortex-X系列)负责爆发力,中核(A78/A710)负责日常主力,小核(A55/A510)负责省电。
但很多开发者没用好。我曾经见过一个App,后台轮询任务跑在了大核上,白白耗电。正确的做法是什么?
- 前台交互任务:丢给中核或大核,保证响应快。
- 后台定时任务:绑定到小核,省电第一。
- 游戏渲染线程:锁定到大核,避免调度抖动。
在联发科平台上,可以用 taskset 或 sched_setaffinity 来绑定CPU。举个例子:
// 将当前线程绑定到CPU2-3(中核)
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(2, &mask);
CPU_SET(3, &mask);
sched_setaffinity(0, sizeof(mask), &mask);
小技巧:联发科的 cpu_capacity 节点可以查看每个核的算力权重。比如大核是1024,小核是400。调度器会根据这个权重分配任务。
另外,大小核切换有个“迁移延迟”。任务从小核搬到大核,需要时间。我建议,如果任务周期短(比如几十毫秒),就别来回迁移了,固定在一个核上反而更高效。
3.3 负载均衡:别让一个核累死,其他核看戏
负载均衡,说白了就是让所有CPU核“雨露均沾”。但联发科的调度器(EAS,Energy Aware Scheduling)不是简单平均分配,而是考虑功耗的。
EAS的核心思想:在满足性能的前提下,尽量用能效比高的核。比如,一个轻任务,小核能搞定,就别往大核上放。
我在项目中遇到过一个问题:手机充电时,某个核温度特别高,其他核却闲着。查了 /proc/stat 和 /sys/devices/system/cpu/cpu*/cpufreq/stats,发现是某个驱动线程绑死了CPU0,导致它一直高频运行。
解决办法:
- 检查是否有线程绑核不合理,用
ps -eLo pid,tid,comm,psr查看。 - 调整调度器参数,比如
/sys/kernel/debug/sched_features里的ENERGY_AWARE开关。 - 如果某个核过热,可以暂时把它从调度池中移除:
echo 0 > /sys/devices/system/cpu/cpu4/online。
警告:不要随意关核!关核后,剩余核的负载会飙升,反而更耗电。只有在散热实在压不住时,才作为临时手段。
最后,分享一个我常用的调优流程:
- 先用
perf top看哪个函数吃CPU最多。 - 再用
trace-cmd抓调度事件,看任务在核间怎么跑的。 - 最后根据数据,调整绑核或governor参数。
嗯,这一章就到这里。记住,CPU调优不是“大力出奇迹”,而是“精准匹配”。下一章咱们聊内存,那又是另一片天地了。
本章小结:
- 频率用
schedutil,别用performance硬怼。 - 大小核要“人尽其才”,后台任务绑小核。
- 负载均衡靠EAS,别手动瞎干预。
公众号:蓝海资料掘金营,微信deep3321