SuperAPI AI 工具集

hz-perfetto-debug

测试与质量

查看项目

更新于 10-15 14:59

技能介绍

Perfetto Debug Skill 用于在 Meta VR 设备上调查 VR 性能问题,适合处理以下场景:帧丢失、卡顿或抖动;CPU 或 GPU 瓶颈;渲染通道开销与 GPU 利用率;热节流与时钟频率变化;帧时序波动与错过 vsync 截止时间;线程争用与同步问题;高绘制调用数或过度绘制。

VR 帧时间目标:不同刷新率有各自的硬性截止时间,超时会导致合成器重投影或用户看到过期帧。120 Hz 为 8.3 ms(Quest 2、Quest 3、Quest 3S 支持);90 Hz 为 11.1 ms(Quest 2、Quest Pro、Quest 3、Quest 3S 支持);72 Hz 为 13.9 ms(所有 Quest 设备默认);60 Hz 为 16.7 ms(仅限媒体应用,Quest 2;交互式应用必须使用 72 Hz 及以上)。即使错过帧截止时间 1 ms 也会产生过期帧(重投影),过期帧超过总帧数 10% 表示存在严重性能问题。

metavr 配置:Perfetto 跟踪由 metavr CLI 提供支持,可将独立二进制文件安装到 PATH(参见 metavr-cli 技能),或通过 npx 免安装调用。下文示例使用裸 metavr 命令;如使用 npm 发行版,请加 npx -y 前缀。采集跟踪前,需通过 USB 连接 Meta VR 设备并开启开发者模式。

快速上手流程:1)采集跟踪,如 metavr perf capture 采集当前运行 VR 应用的 5 秒跟踪,可用 --duration、--app、--gpu-render-stage、--xr-runtime、-o 等参数。未指定 --app 时自动检测前台 VR 应用;CPU 调度与 GPU 指标跟踪默认启用;跟踪会自动拉取到本地。2)列出可用跟踪,metavr perf traces 返回按修改时间排序的 .pftrace 文件,搜索包括 ~/Documents、~/Downloads 和当前工作目录等标准目录。3)加载跟踪,metavr perf load <trace-file>,接受十六进制会话 ID、文件名(可带或不带 .pftrace 扩展名)或完整/相对路径。4)获取性能概览,metavr perf context 返回结构化性能分析,含 CPU 与 GPU 帧时序统计、线程利用率分解、GPU 计数器摘要(若可用)、检测到的瓶颈与建议。5)运行 SQL 查询,metavr perf query <session-id> "...",可对加载的 Perfetto 跟踪数据库执行任意 SQL,可用表包括 slice、thread_track、thread、process、counter、counter_track、args、sched_slice 等。6)分析线程状态,metavr perf thread-state <session-id> <utid>,可加 --start-ts/--end-ts,返回线程 running/sleeping/blocked/等待 CPU 的时间分解,用于判断线程是 CPU 受限、I/O 受限还是饥饿。7)获取 GPU 指标,metavr perf gpu-counters <session-id> --start-ts ... --end-ts ...,返回 GPU 帧区间的度量计数器(均值、标准差、分位数),需至少 20 帧以保证统计准确性,指标包括纹理获取率、着色器 ALU 容量、顶点处理与片元着色统计。

详细分析流程(按顺序):第 1 步验证跟踪质量,确认时长至少 2 秒(理想 3-5 秒)、slice 数量达数千、目标应用进程存在;若少于 1000 个 slice 或不足 1 秒,数据可能不足,需重新采集。第 2 步识别目标进程,用 SQL 查询排除系统服务进程。第 3 步识别游戏引擎,Unity 关键标记为 PlayerLoop、UnityMain、PhaseSync、PostLateUpdate.FinishRendering;Unreal 为 UGameEngine::Tick、FEngineLoop::Tick、RHI Thread;原生 OpenXR 为无引擎标记的 xrWaitFrame、xrBeginFrame、xrEndFrame。第 4 步查找关键线程,包括主线程(UnityMain/GameThread,负责游戏逻辑、物理、脚本)、渲染线程(UnityGfx/RenderThread,负责绘制调用提交)、GPU 完成线程(GPU completion/RHI Thread,负责等待 GPU fence)、工作线程(Job.Worker/TaskGraph,负责并行工作负载);获得线程 utid 后可用 thread-state 快速查看其运行/睡眠/阻塞时间。第 5 步检测帧边界:Unity 用主线程 PlayerLoop slice 定义帧边界;Unreal 用游戏线程 FEngineLoop::Tick slice;OpenXR 用 xrWaitFrame 到 xrEndFrame 序列。第 6 步分析高开销函数,按每帧总耗时排序查找最耗时的调用。第 7 步检查高频调用,每帧调用过多可能表明批处理问题。第 8 步分析 GPU 渲染通道,参见 GPU 分析参考文档了解通道分解、表面分析与 GPU 计数器解读。

Perfetto 关键概念:Slice 是带时间的执行区间(函数调用、帧、渲染通道),含 ts(开始)、dur(持续)、name、track_id;Track 是时间线泳道,线程轨道容纳特定线程的 slice,计数器轨道容纳随时间变化的指标值;Thread(utid)是跟踪内唯一线程 ID,连接时应使用 utid 而非 tid(tid 会被复用);Process(upid)是跟踪内唯一进程 ID,连接时应使用 upid 而非 pid;时间戳均以纳秒为单位,除以 1e6 得毫秒,除以 1e9 得秒;Counter 是时间序列指标(GPU 利用率、时钟频率、温度),存于 counter 表;Args 是附加到 slice 的键值元数据,通过 args 表按 arg_set_id 连接访问。

性能目标参考(指标 / 目标 / 警告 / 严重):帧时间(90 Hz)< 11.1 ms / > 11.1 ms / > 16.7 ms;过期帧率 < 5% / > 10% / > 25%;主线程利用率 < 预算 80% / > 80% / > 95%;GPU 利用率 < 预算 85% / > 85% / > 95%;帧波动(标准差)< 1 ms / > 2 ms / > 4 ms;每帧绘制调用 < 100 / > 200 / > 500。

引擎特定说明。Unity:PhaseSync 是 VR vsync 对齐机制,表现为 PlayerLoop 开始处的空闲时间,属正常且有意图的行为,不要标记为浪费时间;单通道 multiview 一次渲染双眼,若每帧看到两个渲染通道,可能使用了效率较低的多通道渲染;动态批处理方面,高 SetPass 调用数表明材质未被批处理;IL2CPP 与 Mono 的跟踪函数命名不同,IL2CPP 构建会出现修饰过的 C++ 名称而非 C# 方法名。Unreal Engine:RHI Thread 是独立的 GPU 命令提交线程,应检查此线程的驱动开销;前向渲染在 Meta VR 上更受推荐,延迟渲染 GPU 开销显著更高;蓝图 Tick 重度使用表现为 UObject::ProcessEvent,高计数表明应将蓝图转换为 C++;Nativized 蓝图在跟踪名称中带 __StaticExec 后缀。

常见陷阱:不要将 PhaseSync 或 xrWaitFrame 空闲时间报告为性能问题,它们是有意的帧节拍机制;GPU 渲染通道名如 surface#0 不具描述性,需结合分辨率与 MSAA 级别关联判断其渲染内容;线程名在跟踪中可能被截断,UnityMain 可能显示为 UnityMai 等;在 SQL 查询中连接线程相关表时始终使用 utid 而非 tid;时间戳为纳秒,常见错误是当作微秒处理;计数器值是瞬时采样,而非某段时间的平均值。

参考资料:Capturing Traces(如何在 Meta VR 上采集 Perfetto 跟踪)、Analyzing Traces(使用 SQL 查询的分步跟踪分析)、GPU Analysis(渲染通道分析、GPU 计数器与指标)、Frame Timing(VR 帧标记、节拍与合成器时序)、SQL Queries(常见分析任务的现成 SQL 查询)。

限制与缺失:本资料未提供价格、收费模式、许可证、支持平台版本范围、准确用户数量或具体性能提升效果的量化数据,这些信息暂未提供。