3、CPU性能调优基础:理解CPU频率、核心调度、大小核架构(big.LITTLE),学习如何通过sysfs调整CPU调频策略。

好,咱们直接进入正题。CPU调优,说白了就是让芯片在「干活快」和「省电」之间找到平衡点。很多同学一上来就盯着频率猛调,结果要么发热降频,要么功耗爆炸。我刚开始做性能优化时也犯过这错,后来才明白——你得先搞清楚CPU的「脾气」。

3.1 CPU频率:不是越高越好

CPU频率,就是它每秒能跑多少个周期。单位是GHz,1GHz就是每秒10亿次。听起来很爽对吧?但频率越高,电压就得跟着涨,功耗是呈指数级上升的。

核心公式(记牢):

功耗 ∝ 电容 × 电压² × 频率

你看,电压是平方关系。频率翻倍,电压可能得涨20%,功耗直接飙到1.44倍。这就是为什么高通芯片有「温控墙」——不是跑不动,是散热扛不住。

我在项目中遇到过一款游戏手机,跑《原神》时CPU频率锁死在2.8GHz,结果5分钟就降频到1.5GHz。后来我把频率上限降到2.4GHz,电压降了一档,反而全程稳住了2.3GHz。嗯,这就是「降频保帧率」的典型操作。

3.2 核心调度:谁干活,谁休息

高通芯片里通常有8个核心。但8个核心不是一起上的。调度器(Linux内核的CFS或EAS)会决定:哪个任务给哪个核心。

你想想看,如果刷个微信都要大核全开,那电量撑不过半天。所以调度器的原则是:

  • 轻任务(后台同步、通知)→ 丢给小核
  • 中等任务(刷网页、看视频)→ 中核
  • 重任务(游戏渲染、视频编码)→ 大核

我曾经调试过一台设备,发现刷抖音时大核一直在2.0GHz跑。查了半天,原来是某个驱动把线程绑到了大核上。这就是典型的「调度错配」——说白了,杀鸡用了牛刀。

避坑指南:

我曾经在调优时,直接把所有任务都绑到大核上。结果呢?功耗直接翻倍,温度冲到95°C,系统强制关机。后来我学乖了——调度策略要「按需分配」,别贪心。

3.3 大小核架构(big.LITTLE):高通的「田忌赛马」

高通的big.LITTLE架构,说白了就是「大核干重活,小核干轻活」。以骁龙8 Gen 2为例:

核心类型 架构 频率范围 典型用途
超大核(Prime) Cortex-X3 2.0 - 3.2 GHz 游戏、渲染、AI推理
大核(Performance) Cortex-A715 1.8 - 2.8 GHz 应用启动、动画、视频
小核(Efficiency) Cortex-A510 0.8 - 1.8 GHz 后台、待机、轻负载

为什么这么设计?因为不同任务的「性能-功耗曲线」不一样。小核在低频段效率极高,大核在高频段才有优势。你想想看,如果让大核跑800MHz,它的效率反而不如小核——这就是「大材小用」。

我记得有一次调优,发现待机功耗异常高。查了一圈,原来是某个后台服务被调度到了大核上。我手动把它绑到小核后,待机功耗从200mW降到了80mW。嗯,这就是大小核架构的精髓——让合适的核心干合适的活

3.4 通过sysfs调整CPU调频策略

好了,理论讲完了,咱们来点实操。sysfs是Linux内核暴露给用户空间的接口,路径一般在/sys/devices/system/cpu/。你可以直接读写这些文件来调整CPU行为。

3.4.1 查看当前调频策略

# 查看所有核心的调频策略
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

# 输出示例(不同核心可能不同)
cpu0: schedutil
cpu1: schedutil
cpu2: schedutil
...
cpu7: schedutil

常见的governor有:

  • performance:一直跑最高频率,性能拉满,功耗爆炸
  • powersave:一直跑最低频率,省电但卡顿
  • ondemand:负载高了升频,低了降频(老式,延迟大)
  • conservative:缓慢升降频,省电但响应慢
  • schedutil:基于调度器负载的调频,高通推荐(新式,延迟低)

注意:

高通芯片默认用schedutil。我个人不建议换成performance,除非你在跑分。我曾经在测试机上试过performance,结果跑分高了5%,但续航直接腰斩——得不偿失。

3.4.2 手动调整调频策略

# 将cpu0的调频策略改为performance
echo "performance" > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

# 查看当前可用频率
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies

# 手动锁定频率(需要先改为userspace)
echo "userspace" > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
echo 2400000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed

这里要注意:scaling_setspeed的单位是kHz。2.4GHz就是2400000。我习惯先查一下scaling_available_frequencies,确保你写的频率是芯片支持的。

3.4.3 核心在线/离线控制

# 查看核心是否在线
cat /sys/devices/system/cpu/cpu0/online

# 将cpu7离线(关掉超大核)
echo 0 > /sys/devices/system/cpu/cpu7/online

# 重新上线
echo 1 > /sys/devices/system/cpu/cpu7/online

这个操作在调试时很有用。比如你想测试「只用小核跑游戏会怎样」,就可以把大核全部离线。我曾经用这招排查过一个功耗问题——关掉大核后,待机功耗从150mW降到了50mW,说明大核没正常休眠。

3.4.4 调频延迟与采样率

# 查看schedutil的调频延迟
cat /sys/devices/system/cpu/cpu0/cpufreq/schedutil/up_rate_limit_us
cat /sys/devices/system/cpu/cpu0/cpufreq/schedutil/down_rate_limit_us

# 调整升频延迟(单位微秒)
echo 5000 > /sys/devices/system/cpu/cpu0/cpufreq/schedutil/up_rate_limit_us

这个参数很关键。升频延迟越小,响应越快,但频繁调频会增加功耗。我一般设成5ms(5000微秒),既能保证流畅,又不会太激进。

我的调优习惯:

先跑一个基准测试(比如Geekbench),记录帧率和功耗。然后调整up_rate_limit_us到10ms、5ms、2ms,分别测试。你会发现,从10ms降到5ms,帧率提升明显;但从5ms降到2ms,提升就很小了,功耗反而涨了10%。这就是「边际效应」——找到那个平衡点。

3.5 实战:一个完整的调优流程

假设你有一台骁龙8 Gen 2的设备,跑《王者荣耀》时帧率不稳。我会这么做:

  1. 先看现状:用cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq查看各核心实时频率
  2. 检查调度:用top -Hperf top看哪个核心负载高
  3. 调整策略:把游戏线程绑到大核上(用taskset),同时把调频策略设为schedutil
  4. 微调参数:把up_rate_limit_us从10ms降到5ms
  5. 验证效果:跑15分钟游戏,看帧率曲线和温度

我曾经用这套流程,把一台设备的《王者荣耀》帧率从平均55帧提到了59帧,温度还降了3°C。嗯,关键就是「别让大核闲着,也别让小核累着」。

总结一下:

  • 频率不是越高越好,电压和功耗才是瓶颈
  • 大小核架构的核心是「任务匹配」
  • sysfs是调优的入口,但别乱改
  • 调优要「先测量,后调整,再验证」

下一章咱们会深入CPU调频Governor的源码分析,看看schedutil到底是怎么算负载的。到时候你会明白,为什么高通推荐用schedutil而不是ondemand——说白了,就是延迟更低,更懂你的任务。