内容提要
本文介绍 Perfetto 中 GPU、功耗等硬件 counter 的归因方法。核心观点是:GPU 频率、计数器、电池电流和电源轨均不能单独证明 GPU 瓶颈,必须与 FrameTimeline、RenderThread、SurfaceFlinger 在同一时间窗口对齐分析。文中提供设备能力查询、短 Trace 配置、GPU render stages、频率、内存、power rails 与 battery counters 的查询示例,并强调缺失信号应写“无证据”而非反证,GPU 内部问题需转 AGI 等厂商工具。
延伸解读
硬件 counter 的定位:排除错误方向,而非直接定罪
GPU 频率、计数器、电池电流和电源轨都不能单独证明 GPU 瓶颈。频率只说明调频策略给了什么档位,不等于利用率;电池电流是整机口径,包含所有硬件和 App;电源轨是子系统能量口径,也不是进程口径。这些信号的价值在于帮助排除错误方向:问题到底在 CPU 侧、GPU 侧、合成侧、内存带宽,还是功耗/温控策略。只有与 FrameTimeline、RenderThread、SurfaceFlinger 在同一时间窗口对齐,才能推进归因。
设备能力差异大,抓取前先查 descriptor
GPU counter 不是 Android 通用能力,不同 GPU 厂商的 counter 名称和可用性差异很大。抓取前应通过 Perfetto UI 的 Record 页或 adb shell perfetto --query --long 查询数据源 descriptor,确认 producer 名称、counter ID、单位和名称选择能力。常见 producer 带硬件后缀,如 gpu.counters.adreno 或 gpu.renderstages.mali,TraceConfig 必须写精确名称。
缺失信号写“无证据”,不能当反证
很多设备没有 GPU render stages、power rails 或 thermal 轨道。当这些信号缺失时,报告应写“本 trace 无对应证据”或“设备不支持”,而不是“没有 GPU 问题”或“没有温控影响”。例如没有 render stages 时只能写 gpu_stage_status=unavailable,不能拿频率或 power rail 补位成 GPU 执行结论。同样,power rail 元数据为空时,不能写“GPU rail 没升高”,只能写没有可用的 power rail 元数据。
功耗分析是 A/B 实验,不是单次 trace 定罪
功耗问题受屏幕亮度、刷新率、网络、温度、后台任务、USB 供电等多因素影响,单次采样不足以归因到某个 App。更合理的做法是控制变量,在同一设备上比较两个版本或两种实现,使用窗口均值、中位数或稳定区间,而不是单点峰值。Battery current 是整机口径,符号方向只说明电池充放电状态,不等于某个 rail 或 App 的功耗。报告必须同时写明 USB/充电状态和供电控制方式。
Q&A
Perfetto 中 GPU 频率升高是否就能证明 GPU 是瓶颈?
不能。GPU 频率高只说明调频策略把频率抬起来了,不等于 GPU 已经满载或瓶颈。必须与 FrameTimeline、RenderThread、SurfaceFlinger 在同一时间窗口对齐分析,并结合 GPU render stages、GPU counters 等证据,才能判断 GPU 是否真正导致帧延迟。
在 Perfetto 中分析 GPU 和功耗问题时,需要采集哪些硬件 counter?
值得采集的硬件数据包括:GPU render stages、GPU frequency、GPU memory、GPU counters、GPU work period、battery counters 和 power rails。但并非所有设备都支持,需先通过 `adb shell perfetto --query --long` 查询设备能力,确认 producer 名称、counter ID 和单位。
Perfetto 抓不到 GPU render stages 时,报告应该怎么写?
应写“缺少 GPU stage 证据”,不能把频率或 power rail 直接升级成 GPU 执行结论。报告需明确:gpu_stage_status=unavailable; conclusion_scope=hardware_trend_only; cannot_claim=gpu_execution_delay。
Perfetto 中 power rails 和 battery counters 有什么区别?
Power rails 是子系统能量口径,能看到 GPU、Display、Memory 等 rail 的能量变化,依赖 ODPM 硬件和 IPowerStats HAL;battery counters 是整机电池口径,包含整机电流、电压、电量,受 USB/充电状态影响。两者都不是进程口径,不能直接归因到某个 App。
如何用 PerfettoSQL 查询问题窗口内的 GPU 频率?
先引入标准库模块 `INCLUDE PERFETTO MODULE android.gpu.frequency;`,然后定义目标窗口(如 30s 到 45s),查询 `android_gpu_frequency` 表,筛选与窗口重叠的记录,输出 ts、dur、gpu_id 和 gpu_freq_raw。注意 gpu_freq_raw 单位需按设备标注,不能跨设备直接比较裸值。
Perfetto 和 AGI 在 GPU 性能分析中如何分工?
Perfetto 负责系统时间关系:问题帧前后主线程、RenderThread、SurfaceFlinger、Binder 是否异常,GPU render stages 是否晚于目标窗口,频率、power rails、thermal 是否同窗变化。AGI 负责 GPU 内部细节:render pass、draw call、shader、pipeline state,以及 fragment、vertex、texture、bandwidth 等 counter 的专项解释。重场景常需两者结合。
在 Perfetto 中分析 GPU 和功耗问题时,推荐的排查顺序是什么?
推荐顺序:1. 用 FrameTimeline 找问题帧或窗口;2. 看主线程、RenderThread、SurfaceFlinger 是否错过时机;3. 看 GPU render stages/completion 是否跨过目标窗口;4. 看 GPU frequency 变化;5. 查 GPU counters 或 AGI 判断专项方向;6. 查 power rails/battery current 判断功耗约束;7. 回到系统 Trace 看 Binder、CPU 竞争等是否解释同一时间段。
Perfetto 中 GPU counters 的采样周期设置需要注意什么?
GPU counters 采样周期需谨慎:1ms 能看细节,但开销和数据量都更高,长时间现场 Trace 不适合默认打开。短 Trace 可允许 1ms 采样,但长 Trace 需放宽采样周期、拆 buffer,并实测写入速率和 CPU 开销。