ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

高通Thermal Engine温控配置详解:从原理到实战调优

高通Thermal Engine温控配置详解:从原理到实战调优 1. 从一次游戏掉帧说起为什么要动温控配置文件去年帮一个做手游的朋友调一台骁龙8 Gen 2的机器现象很典型开局十分钟稳如老狗二十分钟后帧率从120掉到70机身背面烫得能煎蛋。用Perfetto抓了一把trace发现CPU大核被死死摁在1.2GHzGPU频率也砍了一半——不是性能不够是温控提前介入了。这就是Thermal Engine在干活。高通平台的温控体系里thermal-engine.conf是最核心的那份配置文件。它决定了什么温度下触发什么动作是降频、关核、限制充电电流还是直接让调制解调器降功率。厂商出厂时为了兼顾续航、发热和稳定性往往把阈值调得相当保守尤其是中低端机型稍微跑点重载就降频。对于做性能调优、游戏加速、或者单纯想让老机器再战两年的玩家来说改这份配置是最直接有效的手段之一。这篇内容面向三类人一是Android系统开发/驱动工程师需要理解高通温控框架的运作逻辑二是ROM定制和性能调优爱好者想动手改配置但不知道从哪下手三是遇到温控异常比如低温就降频、充电发热严重需要排查问题的维护人员。我会从Thermal Engine的整体架构讲起把thermal-engine.conf的语法、常见配置项、修改方法、验证手段和踩坑经验全部摊开讲。看完你至少能做到看懂一份出厂配置、按需调整阈值、验证修改是否生效、以及知道哪些参数动了会出事。需要提前说明的是不同高通平台从早期的msm8998到最新的SM8650/kalama配置格式有差异厂商还会做二次定制所以本文给的是通用方法论加典型示例具体数值你得结合自己机器的实际热特性来定。我手头常用的测试平台覆盖了msm8998、sm8250、sm8450和sm8550几代下面的例子会尽量标注平台差异。2. Thermal Engine到底是个什么东西2.1 它在Android热管理里的位置Android的热管理是分层的。最上层是Framework的ThermalService和ThermalManager负责给应用上报热状态THERMAL_STATUS_LIGHT/MODERATE/SEVERE等中间是HAL层高通平台用的是android.hardware.thermal的vendor实现最底层才是真正干活的Thermal Engine守护进程。Thermal Engine是一个跑在native层的daemon开机时由init根据init.thermal-engine.rc拉起读取/vendor/etc/thermal-engine.conf部分平台在/system/etc/或/vendor/etc/thermal-engine/目录下。它持续从各个thermal zone读取温度跟配置里的阈值比对一旦越界就执行预设动作。这些动作通过内核的sysfs节点或者QMI接口下发比如写/sys/class/thermal/thermal_zoneX/policy或者调用thermal_engine自己的client接口去限制CPU/GPU。跟内核自带的thermal governor比如step_wise、power_allocator相比Thermal Engine的优势在于策略更灵活、可配置粒度更细。内核governor只能做简单的降频而Thermal Engine可以同时协调CPU、GPU、充电、调制解调器、相机等多个子系统还能做多级联动。代价就是配置复杂改错了容易出各种诡异问题。2.2 配置文件的基本结构thermal-engine.conf本质是一个文本格式的规则文件由若干条监控-动作规则组成。每条规则大致长这样[SS-GPU] algo_type monitor sensor gpu sampling 1000 thresholds 55000 60000 65000 thresholds_clr 50000 55000 60000 actions gpu gpu gpu action_info 500000000 300000000 200000000拆开看几个关键字段algo_type算法类型最常见的是monitor阈值监控还有pid闭环控制、ss简单监控等。绝大多数场景用monitor就够了。sensor监控哪个温度传感器。名字必须跟/sys/class/thermal/thermal_zone*/type里的一致写错了这条规则直接失效。sampling采样间隔单位毫秒。1000就是每秒读一次。thresholds触发阈值单位是毫摄氏度。55000就是55摄氏度。可以写多个对应多级动作。thresholds_clr清除阈值温度降到这里就撤销对应动作。必须比thresholds低否则会来回抖动。actions触发时执行什么动作跟thresholds一一对应。action_info动作的参数比如降频到多少Hz。这里有个容易踩的坑thresholds和thresholds_clr的数量必须一致而且清除值要严格小于触发值。我见过有人图省事把清除值设得跟触发值一样结果温度在阈值附近反复横跳CPU频率像抽风一样忽高忽低帧率曲线跟心电图似的。2.3 常见sensor和action对照不同平台的sensor命名差异挺大下面这张表是我从几台机器上整理出来的常见对照实际以你机器上thermal_zone的type为准sensor名称含义典型平台cpuCPU综合温度全平台gpuGPU温度全平台pa功率放大器温度全平台quiet_therm主板/电池附近全平台skin外壳温度sm8250vbat电池温度全平台xo_therm晶振温度部分平台modem调制解调器全平台action的类型也很多常用的有action作用action_info含义cpu限制CPU频率目标频率Hzgpu限制GPU频率目标频率Hzcluster限制某个clustercluster号频率hotplug关闭核心核心掩码modem限制调制解调器等级battery限制充电电流mAcamera限制相机等级注意action_info的单位和含义完全取决于action类型写错单位是新手最常见的错误。比如cpu的action_info是Hz写成MHz的话500000000写成500实际效果就是频率被限制到500Hz机器直接卡死。3. 动手前的准备工作3.1 确认你的机器能不能改不是所有机器都能随便改thermal-engine.conf。前提条件有三个第一机器得root。Thermal Engine进程以root权限运行配置文件在/vendor分区没有root权限你连读都读不了。部分机型可以解锁bootloader后刷入Magisk获取root。第二/vendor分区得可写。Android 10以后很多机型启用了动态分区和dm-verity/vendor是只读的。你需要先adb disable-verity再adb remount或者用Magisk模块的方式覆盖。我一般推荐后者因为直接改分区容易在OTA后失效而且改坏了不好恢复。第三得知道Thermal Engine有没有被厂商替换。有些厂商尤其是国内几家会用自己的热管理方案把高通的Thermal Engine禁用了这种情况下改配置文件没用。判断方法adb shell ps -A | grep thermal如果看到thermal-engine进程在跑说明是原生的如果看到的是别的名字那大概率被替换了。3.2 备份备份还是备份这一步我要单独拎出来说。改温控配置最怕的就是改完机器过热保护失效轻则烫手重则烧硬件。动手前必须做两件事一是备份原配置。adb pull /vendor/etc/thermal-engine.conf ./thermal-engine.conf.bak存到电脑上。如果机器已经改过最好把整个/vendor/etc/下跟thermal相关的文件都拉一遍。二是准备好恢复手段。如果改完机器开不了机或者一直重启你需要能进recovery或者fastboot把备份推回去。建议提前确认好自己机器的recovery进入方式以及adb sideload能不能用。实操心得我习惯在改配置前先用adb shell dumpsys thermalservice和adb shell cat /sys/class/thermal/thermal_zone*/temp把当前状态抓一份快照改完之后对比着看能快速判断改动有没有生效。3.3 工具准备需要的工具不多但都得趁手adb和fastboot基础中的基础版本别太老。一个趁手的文本编辑器推荐VS Code或者Notepad能高亮、能对比。别用Windows记事本换行符和编码容易出问题。Perfetto或者atrace用来抓频率和温度的时序验证改动效果。一个能读sysfs的工具adb shell cat就够或者装个Device Info HW之类的App看实时温度。配置文件编码必须是UTF-8无BOM换行符用LF。我见过有人用记事本改完保存成CRLF结果Thermal Engine解析失败直接不启动机器烫得能烤红薯。4. 逐项拆解配置里每个参数该怎么调4.1 阈值设定从拍脑袋到看数据阈值设定是改温控的核心也是最容易拍脑袋出错的地方。很多人一上来就把阈值往上调10度觉得这样性能就释放了结果机器烫得握不住电池寿命也受影响。正确的做法是先测再定。具体步骤第一步抓一份原厂状态下的温度-频率曲线。用Perfetto抓一段重载场景比如跑《原神》或者安兔兔压力测试的trace导出CPU/GPU频率和各个thermal zone的温度。你会看到温度爬到某个点后频率开始往下掉那个点就是原厂的触发阈值。第二步确定你的目标。如果是游戏场景你希望帧率稳定那阈值可以适当上浮但要保证外壳温度不超过45度人体舒适上限。如果是充电场景那重点是把充电电流和温度解耦避免边充边玩时过热。第三步设定新的阈值。我的经验是触发阈值比原厂高3到5度清除阈值比触发阈值低5到8度。这个间隔是为了避免抖动。比如原厂GPU在55度触发降频你可以改成58度触发、52度清除。这里有个计算示例。假设你的机器外壳温度在GPU 55度时是42度你想让外壳最高到44度那GPU阈值最多上浮到58度左右。因为GPU温度和外壳温度大致是线性关系每上浮1度GPU温度外壳大概涨0.5到0.7度。这个系数因机器散热设计而异得自己测。4.2 多级降频别一刀切原厂配置经常是一到阈值就砍到最低比如GPU直接从600MHz砍到200MHz这种断崖式降频对帧率稳定性是灾难。更好的做法是多级降频温度越高降得越多给系统一个缓冲。举个例子把原来的单级改成三级[SS-GPU] algo_type monitor sensor gpu sampling 1000 thresholds 55000 58000 61000 thresholds_clr 50000 53000 56000 actions gpu gpu gpu action_info 500000000 400000000 300000000这样55度降到500MHz58度降到400MHz61度才降到300MHz。相比一刀切帧率曲线会平滑很多。代价是高温区间停留时间变长需要配合更好的散热。注意事项多级降频的每一级之间频率差不要太接近否则实际效果跟单级差不多。我一般让相邻两级差至少100MHz具体看GPU的频率档位。4.3 采样间隔快慢之间的权衡sampling这个参数看着不起眼实际影响很大。设得太快比如100msCPU会频繁被唤醒去读温度增加功耗设得太慢比如5000ms温度已经冲上去了才反应过来降频滞后。我的经验值CPU和GPU的监控用1000ms电池和充电相关的用2000到3000ms调制解调器用5000ms。这个配置在性能和功耗之间比较平衡。有个特殊情况如果你发现温度在阈值附近抖动得厉害可以把sampling调大一点相当于加了低通滤波。但别超过3000ms否则响应太慢。4.4 动作参数频率、核心、电流action_info的设定要结合具体场景。以CPU为例限制频率时不要直接写一个绝对值而是参考CPU的可用频率表。你可以从/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies读到所有档位选一个比当前低一档的值。关核hotplug要慎用。有些配置会在高温时关掉大核只留小核跑。这在待机场景没问题但游戏场景下关大核会导致帧率暴跌。我的建议是除非温度真的失控比如超过75度否则不要用hotplug优先用降频。充电限流battery action的action_info单位是mA。原厂经常在45度就限到500mA充电慢得让人抓狂。如果你的机器散热还行可以放宽到40度限1500mA、45度限800mA。但要注意充电发热跟电池健康直接相关别为了快充把电池搞鼓包了。5. 完整实操从改配置到验证生效5.1 拉取并解读原配置先连上机器把原配置拉下来adb root adb remount adb pull /vendor/etc/thermal-engine.conf ./thermal-engine.conf打开文件先别急着改通读一遍。重点看几个地方有哪些sensor被监控了、阈值大概在什么范围、有没有你机器特有的配置段。不同厂商的配置差异很大有的把配置拆成多个文件放在/vendor/etc/thermal-engine/目录下用include语句引用。我手头一台sm8450的机器原配置里有这么一段[CPU0_MONITOR] algo_type monitor sensor cpu sampling 1000 thresholds 60000 65000 70000 thresholds_clr 55000 60000 65000 actions cpu cpu cpu action_info 1800000 1500000 1200000意思是CPU到60度限1.8GHz65度限1.5GHz70度限1.2GHz。这个策略偏保守60度就动手了。我把它改成65/70/75触发60/65/70清除频率改成2.0/1.7/1.4GHz。5.2 修改并推送改的时候用编辑器别用sed之类的命令行工具直接改容易出错。改完保存确认编码是UTF-8无BOM、换行是LF。推送回去adb push ./thermal-engine.conf /vendor/etc/thermal-engine.conf adb shell chmod 644 /vendor/etc/thermal-engine.conf adb shell chown root:root /vendor/etc/thermal-engine.conf权限和属主必须对否则Thermal Engine读不了。644是标配属主root:root。然后重启Thermal Engine进程让它重新加载配置adb shell pkill thermal-engine进程会被init自动拉起。或者直接重启机器更稳妥。5.3 验证修改是否生效验证分两步。第一步看进程有没有正常起来adb shell ps -A | grep thermal应该能看到thermal-engine进程PID是新的。如果进程没起来说明配置有语法错误去看adb logcat | grep thermal或者adb shell dmesg | grep thermal找报错。第二步看实际效果。跑一个重载场景同时抓温度和频率adb shell while true; do cat /sys/class/thermal/thermal_zone0/temp; cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq; sleep 1; done观察温度爬到新阈值时频率有没有按预期下降。如果温度到了65度频率还是满血说明配置没生效回去检查sensor名字和action参数。实操心得我习惯用Perfetto抓一段完整的trace然后在界面上把温度和频率叠在一起看比命令行直观得多。Perfetto的android.cpu.frequency和android.power.thermal两个数据源就够用了。5.4 一个完整的配置示例下面是我在一台sm8250机器上用的配置片段覆盖了CPU、GPU和充电三个场景可以直接参考[CPU_MONITOR] algo_type monitor sensor cpu sampling 1000 thresholds 65000 70000 75000 thresholds_clr 60000 65000 70000 actions cpu cpu cpu action_info 2000000 1700000 1400000 [GPU_MONITOR] algo_type monitor sensor gpu sampling 1000 thresholds 58000 62000 66000 thresholds_clr 53000 57000 61000 actions gpu gpu gpu action_info 500000000 400000000 300000000 [BATTERY_MONITOR] algo_type monitor sensor vbat sampling 3000 thresholds 40000 45000 48000 thresholds_clr 38000 43000 46000 actions battery battery battery action_info 2000000 1000000 500000这套配置在我这台机器上实测跑《王者荣耀》120帧模式前30分钟帧率稳定在115以上外壳最高43度充电时40度开始限流从30W降到15W左右电池温度控制在42度以内。6. 常见问题与排查实录6.1 改完不生效的几种可能这是问得最多的问题。按概率排序原因通常是这几个第一配置文件路径不对。不同平台路径不一样常见的有/vendor/etc/thermal-engine.conf、/system/etc/thermal-engine.conf、/vendor/etc/thermal-engine/thermal-engine.conf。用find / -name thermal-engine.conf 2/dev/null找一下。第二sensor名字写错。Thermal Engine对sensor名字是精确匹配的大小写、下划线都不能错。用cat /sys/class/thermal/thermal_zone*/type核对。第三厂商用了自己的热管理方案。前面说过判断方法是看进程名。第四dm-verity没关改动被还原了。重启后adb shell cat一下配置文件看是不是变回原样了。6.2 温度抖动和频率抽风现象是频率在阈值附近反复横跳帧率忽高忽低。根因是thresholds和thresholds_clr间隔太小或者sampling太快。解决办法把清除阈值往下调让触发和清除之间至少有5度的间隔或者把sampling从1000调到2000。我一般两个一起调效果最明显。6.3 机器过热或自动关机这是最危险的情况说明你的阈值调得太高或者动作参数写错了导致降频没生效。立即恢复备份配置重启机器。预防措施改配置时不要一次调太多每次只改一个sensor的阈值验证没问题再改下一个。另外改完先用轻载场景比如刷视频跑十分钟确认温度正常再上重载。6.4 充电变慢或充不进去多半是battery action的阈值设太低或者action_info的电流设太小。检查vbat相关的配置段把阈值上浮3到5度电流适当放大。但要注意电池温度超过45度还大电流充电长期下来电池会鼓包这个度得把握好。6.5 常见问题速查表现象可能原因排查方法解决配置不生效路径错/sensor名错/被厂商替换核对路径和sensor名看进程改对路径确认用原生Thermal Engine频率抖动阈值间隔小/sampling快看trace里频率曲线加大清除间隔调大sampling过热关机阈值过高/动作失效看温度是否超过设定值恢复备份降低阈值充电慢电池阈值低/电流小看充电时的温度和电流上浮阈值放大电流进程起不来配置语法错/编码错logcat和dmesg检查语法确认UTF-8无BOM避坑技巧改配置时养成习惯每次只改一个变量改完立即验证。我见过有人一次性改了五六个参数出问题后根本不知道是哪个引起的只能全部回滚重来。7. 进阶玩法让温控更聪明7.1 结合场景动态切换配置固定一套配置很难兼顾所有场景。待机时希望温控激进一点省电游戏时希望保守一点保性能。Thermal Engine本身不支持动态切换但可以通过init触发或者写个简单的脚本根据当前前台应用替换配置文件再重启进程。具体做法写一个shell脚本用dumpsys activity判断当前前台包名如果是游戏就推游戏版配置否则推日常版配置。脚本挂到init.rc的on property触发或者用Tasker之类的工具定时执行。7.2 用PID算法做平滑控制monitor算法是阶梯式的温度到了就跳变。如果想要更平滑的控制可以用pid算法。它的配置长这样[GPU_PID] algo_type pid sensor gpu sampling 1000 set_point 60000 set_point_clr 55000 action gpu action_info 600000000PID算法会根据温度偏差动态调整频率而不是硬跳变。缺点是调参麻烦Kp、Ki、Kd三个系数得慢慢试。我一般只在GPU上用CPU还是用monitor因为CPU的频率档位多monitor的多级配置已经够平滑了。7.3 监控外壳温度而不是芯片温度芯片温度到70度其实很正常但外壳到45度用户就受不了了。如果你的机器有skin传感器优先用它做阈值判断比用cpu/gpu更贴近用户体验。没有skin的话可以用quiet_therm近似它测的是主板温度跟外壳相关性比较高。用skin做监控的配置示例[SKIN_MONITOR] algo_type monitor sensor skin sampling 2000 thresholds 42000 44000 46000 thresholds_clr 40000 42000 44000 actions cpu gpu battery action_info 1800000 400000000 1000000这样外壳到42度就开始温和降频到46度才下狠手用户感知会好很多。8. 我踩过的几个坑第一个坑是编码问题。早期用Windows记事本改配置保存后Thermal Engine直接不启动查了半天才发现是BOM头的问题。后来养成习惯一律用VS Code右下角确认UTF-8和LF。第二个坑是sensor名字。有次在一台机器上写gpu死活不生效后来发现那台机器的GPU传感器叫gpu_therm。不同平台命名真的没规律必须实地核对。第三个坑是阈值调太猛。有次为了跑分把CPU阈值从60度直接拉到75度结果跑分是上去了但机器背面烫得没法握而且跑完分电池温度到了48度吓得我赶紧改回来。温控这东西性能和安全之间必须留余量。第四个坑是忘了关dm-verity。改完配置重启发现全变回原样了白忙活一场。后来每次改之前先adb disable-verity确认/vendor可写再动手。第五个坑是action_info单位。有次把CPU频率写成2000本意是2GHz结果机器卡成PPT因为实际限制到了2000Hz。这个错误很低级但很致命写参数时一定要对着单位表核对。9. 最后分享几个实用技巧如果你只是想微调不想大动干戈有个偷懒的办法只改thresholds_clr把清除阈值往下调触发阈值不动。这样降频还是按原厂的来但恢复会更晚相当于变相延长了高性能时间。风险比直接调触发阈值小很多。另一个技巧是善用include。如果配置拆成多个文件可以建一个自己的覆盖文件用include引进去这样OTA升级时原厂文件被覆盖了你的改动还在。具体语法是include /vendor/etc/thermal-engine/custom.conf放在主配置的最后。还有改完配置后建议跑一轮完整的充放电循环观察电池温度曲线。有些问题比如充电限流没生效在短时间测试里看不出来得跑完整循环才暴露。这套东西我前后折腾了大概两年从最早的msm8998到现在的sm8550配置格式变了不少但核心逻辑没变理解sensor、定好阈值、选对动作、验证效果。把这四步做扎实温控调优就不会出大问题。
返回列表