移动端 CPU 调度分析:线程亲和性、大小核迁移与卡顿
Game Thread 耗时突然升高,不一定是执行了更多代码。线程迁移到不同核心、频率变化、优先级反转和运行队列竞争,都可能让相同工作变慢。本文用调度时间线区分计算成本与调度成本。
一、运行时间不等于墙上耗时
一个任务墙上耗时 12 ms,真正获得 CPU 的时间可能只有 6 ms,其余时间在等待调度、锁或系统事件。分析时拆分:运行、可运行但未调度、睡眠等待和锁等待。
二、核心类别和频率
移动 SoC 常包含不同性能与能效核心。记录线程在哪类核心运行、迁移次数、频率分布和运行队列。公开分析应使用核心类别,不依赖未公开硬件细节。
三、迁移的成本
迁移可能带来缓存局部性损失,但完全固定亲和性也会限制调度器并造成热点。先确认迁移与长帧在多次运行中一致,再做受控亲和性实验。不能看到迁移就直接判定为根因。
四、优先级反转
高优先级线程等待低优先级持锁线程,而后者又被其他工作抢占,会放大等待。Trace 中应关联锁持有者、等待者和其调度状态,而不仅看等待线程栈。
五、线程池过量
工作线程过多会增加竞争、切换和缓存压力。统计同时可运行线程数、队列长度、任务粒度和核心利用率。小任务过度拆分可能让调度成本超过并行收益。
六、验证实验
- 固定相同工作量,比较运行时间与等待时间;
- 限制后台线程数量,观察关键线程延迟;
- 改变任务粒度,检查切换与队列;
- 在允许条件下做短期亲和性对照;
- 同时控制热状态,避免频率差被误判为调度问题。
七、结论边界
调度轨道显示的是操作系统实际安排,但修复未必是"绑核"。减少主线程同步点、缩短锁、控制线程数量、调整任务优先级和降低后台突发,通常比静态绑核更稳健。
结语
CPU 卡顿归因必须回答线程是在执行、等待还是排队。把核心类别、频率、运行队列和锁关系放进同一时间线,才能避免把调度延迟误当成代码热点。