☰
AGI揭秘:精准定位性能瓶颈的终极武器
2026/10/8 13:56:46 网站建设 项目流程

它补的是哪块空白

前面几篇用的工具各有盲区:

Unity Profiler CPU 侧耗时分布,GPU 只给一个粗略总数 Frame Debugger 画了什么、合批如何 —— 但完全没有耗时 Perfdog 帧率/温度/功耗曲线 —— 不告诉你为什么 AGI GPU 内部:每个 Pass 花多久、卡在哪个阶段、带宽多少 ✅

前面说"降分辨率帧率不变可能是顶点瓶颈",当时只能靠推断。AGI 是直接把数字摆出来的那一步。

它是 Google 出的免费工具(早期叫 GAPID),针对 Android。


一、两种模式,解决不同问题

System Profile(系统追踪) 基于 Perfetto,抓一段时间(几秒)的全系统数据 → CPU 各核调度、GPU 占用率与频率、内存带宽 → vsync、帧提交节奏、卡顿点 → 回答:瓶颈在哪一侧?有没有降频?卡顿发生在什么时刻? Frame Profile(单帧分析) 抓一帧,逐 Render Pass / Draw Call 展开 → 每个 Pass 的 GPU 耗时 → GPU 硬件计数器(片元数、顶点数、纹理采样量、带宽) → 回答:这一帧的时间具体花在哪?

实践顺序通常是:先 System Profile 定性,再 Frame Profile 定位。


二、前置条件(最容易卡住的地方)

这一步失败率很高,先说清。

应用必须是 debuggable

Unity: Build Settings → ☑ Development Build 或者在 AndroidManifest 里: <application android:debuggable="true">
⚠️ Development Build 自带额外开销 → 用它看「比例关系」和「哪个 Pass 贵」✅ → 不要用它的绝对数值下结论 ❌ 想测真实耗时,需要单独出一个 debuggable 的 Release 配置

图形 API 建议用 Vulkan

Player Settings → Other Settings → Graphics APIs 把 Vulkan 拖到第一位

AGI 的 Frame Profile 对 Vulkan 支持最完整。OpenGL ES 的支持情况随 AGI 版本和设备驱动而不同,我没法给你一个可靠的兼容列表——建议直接在目标机型上试一次。

设备支持有限

System Profile: 支持面较广(Perfetto 是 Android 系统能力) Frame Profile: 要求 GPU 驱动暴露性能计数器 → 只有部分机型支持 → Google Pixel 系列、部分 Adreno / Mali 设备

这是 AGI 最大的实用障碍。官方维护一份支持设备列表,用之前先去查,别指望手上任意一台测试机都能用。某些厂商的定制 ROM 会把计数器接口关掉。

连接步骤

① 开发者模式 + USB 调试 ② adb devices 确认能连上 ③ 启动 AGI → 选择设备 → 选择应用包名 ④ 选 System Profile 或 Frame Profile ⑤ Capture
连不上的常见原因: · adb 版本太老 · 应用不是 debuggable · 手机弹了授权框没点(拔插线重试) · 厂商 ROM 限制了性能计数器访问 · 后台有别的 adb 客户端占着(adb kill-server 重试)

三、System Profile 怎么读

抓到的是一张时间轴,上下叠了很多条轨道:

时间 ────────────────────────────────────────────────► VSync │ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │ 16.6ms 一格 CPU 0 (小核) │▓▓░░▓▓░░░░▓▓▓░░░░░░░░░░░░░░░░░░░░░░░│ CPU 4 (大核) │▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓│ ← 主线程满载 CPU 7 (超大核)│▓▓▓▓░░░░▓▓▓▓░░░░▓▓▓▓░░░░░░░░░░░░░░░░│ GPU 占用率 │▓▓▓▓▓▓▓░░░░▓▓▓▓▓▓░░░░▓▓▓▓▓░░░░░░░░░░│ 约 60% GPU 频率 │━━━━━━━━━━━━╲____________________────│ ← 降频了 UnityMain │████████████████████████████████████│ RenderThread │ ███ ███ ███ ███ ███ │

要盯的四件事

① GPU 占用率

持续 > 95% GPU bound,去做 Frame Profile 50% ~ 80% GPU 有余力 → 瓶颈在 CPU 或提交节奏 剧烈波动 负载不均,某些帧特别重

② GPU 频率曲线

这是 System Profile 独有的价值——看降频。

频率 │ │━━━━━━━━╲ │ ╲________________ │ ← 稳定在低频 └──────────────────────────► 时间 2min 频率掉下来,帧率跟着掉 → 这不是渲染效率问题,是功耗/温度问题 → 优化方向是「降低整体功耗」,不是「优化某个 Pass」

带宽、Overdraw、过多的 RT 切换都是发热大户。前面讲的 tile 相关优化,收益主要体现在这条曲线上。

③ CPU 各核分布

只有一个核满载,其他闲着 → 主线程瓶颈,考虑 Jobs / 多线程渲染 频繁在大小核之间迁移 → 线程亲和性问题,或者系统调度在省电

④ 主线程和渲染线程的关系

UnityMain │████████████████│ 满 RenderThd │ ██ ██ ██ │ 有空隙 → CPU 提交端是瓶颈 UnityMain │██ ██ ██ ██ │ 有空隙 RenderThd │████████████████│ 满 → 渲染线程或 GPU 是瓶颈

四、Frame Profile 怎么读

抓一帧,左边是 Render Pass 树,每项带 GPU 耗时:

Frame 18.4 ms ├─ RenderPass: ShadowMap 3.8 ms 21% │ ├─ Cascade 0 1.1 ms │ ├─ Cascade 1 0.9 ms │ ├─ Cascade 2 0.8 ms │ └─ Cascade 3 1.0 ms ├─ RenderPass: Opaque 7.2 ms 39% │ ├─ Draw (terrain) 2.1 ms │ ├─ Draw (characters) ×8 2.8 ms │ └─ Draw (props) ×120 2.3 ms ├─ RenderPass: Transparent 4.1 ms 22% ← 偏高 │ └─ Draw (particles) ×40 3.7 ms ← 这里 ├─ RenderPass: PostProcess 2.6 ms 14% │ ├─ Bloom downsample ×4 0.9 ms │ ├─ Bloom upsample ×4 0.8 ms │ └─ UberPost 0.9 ms └─ RenderPass: UI 0.7 ms 4%

这张表就是前面所有工具给不了的东西。Frame Debugger 能告诉你有 40 个粒子 Draw Call,只有 AGI 告诉你它们吃了 3.7ms,占了整帧的 20%。

第一眼先看占比

看到 Transparent 22% 还只画了 40 个粒子 → 典型的 Overdraw 问题 → 对上了前面讲的「半透明不能深度剔除」 看到 ShadowMap 21% → 阴影确实是双倍成本的实证 → 砍 Max Distance / 减级联,这里会直接下来 看到 PostProcess 14% 全是 Blit → 全屏带宽开销,低端档应该关掉

五、用计数器细分瓶颈

这是 AGI 最核心的能力,也是我前面说"要进一步确认"的那一步。

选中一个 Pass 或 Draw Call,右侧给出 GPU 硬件计数器。具体名称和可用项因 GPU 厂商(Adreno / Mali)而异,但大致分这几类:

几何类 Vertices / Primitives 处理了多少顶点和图元 Vertex Shader Cycles 顶点着色花的周期 Culled Primitives 被剔掉多少 片元类 Fragments Shaded 实际着色的片元数 Fragment Shader Cycles 片元着色周期 Early-Z Killed 被提前剔除的片元 纹理类 Texture Fetches / Cycles 采样次数和开销 Texture Cache Miss 缓存未命中 带宽类 Read / Write Bytes 主内存读写量 Tile Read / Write tile 的 resolve 量

怎么用它们判断

判断 Overdraw

Fragments Shaded ÷ 屏幕像素数 = 实际 Overdraw 倍数 1080p = 207 万像素 Fragments Shaded = 250 万 → 1.2x,很好 Fragments Shaded = 800 万 → 3.9x,偏高 Fragments Shaded = 2000 万 → 9.7x,严重

这个数字比 Scene 视图的 Overdraw 热力图精确得多——它是真机上的实测值,不是编辑器估算。

区分片元 bound 和顶点 bound

Fragment Shader Cycles >> Vertex Shader Cycles → 片元瓶颈 → 简化 Shader / 降分辨率 / 减 Overdraw Vertex Shader Cycles >> Fragment Shader Cycles → 顶点瓶颈 ← 这正是「降分辨率没用」的那种情况 → 做 LOD / 减面 / 合并网格 / 减少阴影 Pass

判断带宽瓶颈

Read + Write Bytes 很大,但 Shader Cycles 不高 → 带宽 bound,GPU 在等内存 → 压纹理 / 开 Mipmap / 减 RT 切换 / 减分辨率 典型的带宽大户: · 未压缩纹理 · 没开 Mipmap(缓存命中率极低) · 一串全屏 Blit · 大尺寸 RenderTarget

判断 Shader 太复杂

Shader Cycles ÷ Fragments Shaded = 每片元的平均开销 这个值高 → Shader 本身重 → 查是否有逐像素光照、多层采样、复杂数学 → 对照 Frame Debugger 看 Keywords 是否过多

判断纹理缓存问题

Texture Cache Miss 比例高 → 大概率是没开 Mipmap → 或者贴图尺寸远超实际需要的采样密度 这直接验证了前面说的「不开 Mipmap 省内存是错误优化」

六、串起来的完整诊断流程

把前面几篇的工具连成一条线:

① Perfdog / System Profile 跑 20 分钟,看帧率和 GPU 频率曲线 ↓ 频率掉了?→ 功耗问题,重点查带宽和 Overdraw 频率稳定?→ 继续 ↓ ② Unity Profiler + 降分辨率测试 定性:CPU bound 还是 GPU bound ↓ CPU bound → 走 CPU 优化路线(脚本/物理/UI/GC) GPU bound → 继续 ↓ ③ Frame Debugger 看结构:画了什么、合批如何、有无多余 Pass ↓ ④ AGI Frame Profile 看耗时:哪个 Pass 占比最高 ↓ ⑤ AGI 计数器 细分:片元 / 顶点 / 带宽 / Shader 哪一项 ↓ ⑥ 针对性优化 → 回到 ① 验证
⚠️ 每一步都要闭环验证 改完回到 AGI 重抓一次,确认那个 Pass 的耗时真的下来了 不要改完就认为有效

七、常见现象对照

现象AGI 里的特征处理方向
降分辨率无效Vertex Cycles 高,Fragment 低LOD、减面、减阴影 Pass
发热降频GPU 频率曲线下行,带宽计数器高压纹理、减 Overdraw、减 RT 切换
特效一开就卡Transparent Pass 占比高,Fragments 远超像素数减粒子数量/尺寸,序列帧替代叠加
阴影很贵ShadowMap Pass 占比 >20%砍 Max Distance、减级联、关小物件投影
后处理很贵PostProcess 下一串 Blit,Write Bytes 高合并 Pass,低端档关闭
某个材质特别慢单个 Draw 的 Shader Cycles/片元 异常高简化 Shader,查 Keywords
画面没问题但就是慢Texture Cache Miss 高开 Mipmap,检查贴图尺寸
GPU 占用不满但帧率低System Profile 显示 CPU 单核满载CPU 侧优化,考虑 Jobs

八、局限与替代

AGI 的问题: · Frame Profile 设备支持有限,很多机型用不了 ← 最大障碍 · 需要 debuggable 包,数据有额外开销 · 连接不稳定,断连重试是常态 · 只支持 Android · 学习曲线比 Unity 自带工具陡

所以实际项目通常不会只用一个:

需求工具
Adreno 深度分析Snapdragon Profiler(高通官方,计数器更全)
Mali 深度分析Arm Mobile Studio / Streamline
iOS GPU 分析Xcode GPU Frame Capture
长期帧率/温度/功耗Perfdog
快速看结构Unity Frame Debugger
CPU 侧Unity Profiler
实用建议: 主力测试机选一台 AGI 支持的(Pixel 系列最稳) 专门用来做 GPU 深度分析 其他机型用 Perfdog 做覆盖测试,看表现是否一致

要点

1. AGI 填的是「GPU 内部耗时」这块空白 Frame Debugger 看结构,AGI 看耗时,两者配合用 2. System Profile 定性(含 GPU 频率曲线,这是看降频的关键) Frame Profile 定位(逐 Pass 耗时 + 硬件计数器) 3. 前置条件容易卡住:debuggable 包 + Vulkan + 设备在支持列表里 Frame Profile 的设备限制是最大的实用障碍 4. 用 Development Build 看比例关系,不要信绝对数值 5. 计数器的核心用法: Fragments Shaded ÷ 屏幕像素 = 真实 Overdraw Fragment vs Vertex Cycles = 片元 bound 还是顶点 bound Read/Write Bytes 高但周期低 = 带宽 bound Cycles ÷ Fragments = Shader 单位开销 Cache Miss 高 = Mipmap 没开 6. 顶点 bound 是「降分辨率测不出来」的那种情况 AGI 的计数器是确认它的唯一可靠手段 7. GPU 频率下行说明是功耗问题, 优化方向是降带宽,而不是优化某个具体 Pass 8. 改完必须回到 AGI 重抓验证,确认目标 Pass 的耗时真的下来了

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询