mcpField
H
hz-perfetto-debug

hz-perfetto-debug

github.com/meta-quest开发241259 次安装5 周前更新
代码仓库

关于 hz-perfetto-debug

用于诊断 Meta VR 设备性能问题的 Skill,通过 metavr 捕获并分析 Perfetto 跟踪。它指导开发者检查帧时间、CPU/GPU、线程和渲染瓶颈。

主要功能

  1. 01捕获并加载 Perfetto 跟踪
  2. 02查看 CPU 和 GPU 帧时间
  3. 03检查线程状态与利用率
  4. 04用 SQL 查询跟踪数据
  5. 05分析 GPU 计数器与渲染阶段

适用场景

  1. 01排查卡顿或错过帧期限
  2. 02定位 CPU 或 GPU 瓶颈
  3. 03检查线程争用与同步问题
  4. 04分析渲染通道或绘制调用开销

MCP 相关

这是一个 Agent Skill,并非 MCP 服务或客户端;README 未说明 MCP 连接方式。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/meta-quest/agentic-tools --skill hz-perfetto-debug

安装后在 Claude Code 中输入/hz-perfetto-debug确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
analyzing-traces.md
capturing-traces.md
frame-timing.md
gpu-analysis.md
sql-queries.md

详细介绍

Perfetto 调试技能

使用场景

在调查 Meta VR 设备上的 VR 性能问题时使用此技能:

  • 帧丢失、卡顿或画面不流畅
  • CPU 或 GPU 瓶颈
  • 渲染通道开销和 GPU 利用率
  • 温控降频和时钟频率变化
  • 帧计时波动和错过 vsync 截止时间
  • 线程争用和同步问题
  • 绘制调用次数过多或过度绘制

VR 帧时间目标

以下是各刷新率对应的硬性截止时间。如果帧超出目标,合成器必须进行重投影,否则用户会看到过时帧。

刷新率帧时间预算备注
120 Hz8.3 msQuest 2、Quest 3、Quest 3S 支持
90 Hz11.1 msQuest 2、Quest Pro、Quest 3、Quest 3S 支持
72 Hz13.9 ms所有 Quest 设备的默认设置
60 Hz16.7 ms仅限媒体应用(Quest 2);交互式应用必须使用 72 Hz 或更高

即使只错过帧截止时间 1 ms,也会导致出现过时帧(重投影)。过时帧超过总帧数的 10% 表明存在严重的性能问题。

metavr 设置

Perfetto 跟踪由 metavr CLI 提供支持——将独立二进制文件安装到 PATH 中(参见 metavr-cli 技能),或通过 npx 调用,无需安装:

metavr --version

以下示例使用裸 metavr 命令;如果使用 npm 发行版,请在命令前加上 npx -y。开始捕获跟踪前,请通过 USB 连接 Meta VR 设备并启用开发者模式。

快速入门工作流

1. 捕获跟踪
# Capture a 5-second trace from the currently running VR app
metavr perf capture

# Specify duration and target app
metavr perf capture --duration 10000 --app com.example.myapp

# Enable GPU render stage tracing for detailed pass analysis
metavr perf capture --gpu-render-stage

# Enable XR runtime metrics
metavr perf capture --xr-runtime

# Custom output name
metavr perf capture -o my-session-name

如果未指定 --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> "SELECT ts, dur, name FROM slice WHERE name LIKE '%PlayerLoop%' LIMIT 20"

对已加载的 Perfetto 跟踪数据库执行任意 SQL。可使用所有 Perfetto 表:slice、thread_track、thread、process、counter、counter_track、args、sched_slice 等。

6. 分析线程状态
metavr perf thread-state <session-id> <utid>

# With time range
metavr perf thread-state <session-id> <utid> --start-ts 1000000 --end-ts 5000000000

返回线程状态细分情况,显示线程在运行、休眠、阻塞或等待 CPU 上花费的时间。可用于判断线程是受 CPU 限制、受 I/O 限制,还是资源不足。

7. 获取 GPU 指标
metavr perf gpu-counters <session-id> --start-ts 100,200,300 --end-ts 150,250,350

返回 GPU 帧范围的 GPU 指标计数器(均值、标准差、分位数)。为确保统计准确性,至少需要 20 帧。指标包括纹理读取速率、着色器 ALU 容量、顶点处理和片段着色统计信息。

详细分析工作流

按顺序执行以下步骤,全面调查性能问题。

步骤 1:验证跟踪质量

开始分析前,确认跟踪可用:

  • 持续时间:至少 2 秒的数据(最好为 3-5 秒)
  • 切片数量:应有数千个切片,才能构成有意义的跟踪
  • 进程是否存在:必须包含目标应用进程
SELECT
  (MAX(ts) - MIN(ts)) / 1e9 AS duration_seconds,
  COUNT(*) AS total_slices
FROM slice

如果跟踪的切片少于 1000 个,或持续时间不足 1 秒,则可能没有足够的数据用于有意义的分析。请使用 metavr perf capture 重新捕获跟踪。

步骤 2:识别目标进程

查找应用进程(而非系统服务):

SELECT upid, pid, name
FROM process
WHERE name NOT LIKE 'com.oculus%'
  AND name NOT LIKE '/system%'
  AND name NOT LIKE 'com.android%'
  AND name IS NOT NULL
ORDER BY pid

对于已知应用,可直接按软件包名称筛选。

第 3 步:识别游戏引擎

查找特定于引擎的标记:

引擎关键标记
UnityPlayerLoop、UnityMain、PhaseSync、PostLateUpdate.FinishRendering
UnrealUGameEngine::Tick、FEngineLoop::Tick、RHI Thread
Native OpenXRxrWaitFrame、xrBeginFrame、xrEndFrame,且没有引擎标记
第 4 步:查找关键线程

识别 VR 渲染所涉及的线程:

SELECT t.utid, t.tid, t.name, p.name AS process_name
FROM thread t
JOIN process p USING(upid)
WHERE p.name = '<target-process>'
ORDER BY t.name

需要定位的关键线程:

线程用途
主线程(UnityMain / GameThread)游戏逻辑、物理、脚本
渲染线程(UnityGfx / RenderThread)提交绘制调用
GPU 完成线程(GPU completion / RHI Thread)等待 GPU 栅栏
工作线程(Job.Worker / TaskGraph)并行工作负载

获取线程的 utid 后,使用 metavr perf thread-state <session-id> <utid> 快速查看其运行、休眠和阻塞时间。

第 5 步:检测帧边界

查找帧的开始/结束标记,以便按帧划分分析:

  • Unity:主线程上的 PlayerLoop 片段定义帧边界
  • Unreal:游戏线程上的 FEngineLoop::Tick 片段
  • OpenXR:xrWaitFrame 到 xrEndFrame 的序列
第 6 步:分析耗时较长的函数

找出每帧中最耗时的部分:

SELECT name, COUNT(*) AS call_count, SUM(dur)/1e6 AS total_ms, AVG(dur)/1e6 AS avg_ms
FROM slice
WHERE track_id IN (
  SELECT id FROM thread_track WHERE utid = <main_thread_utid>
)
GROUP BY name
ORDER BY total_ms DESC
LIMIT 20
第 7 步:检查高频调用

每帧调用次数过多的函数可能表明存在批处理问题:

SELECT name, COUNT(*) AS calls
FROM slice
WHERE track_id IN (
  SELECT id FROM thread_track WHERE utid = <utid>
)
  AND dur < 100000
GROUP BY name
HAVING calls > 1000
ORDER BY calls DESC
第 8 步:分析 GPU 渲染通道

如需详细了解渲染通道分析、表面分析和 GPU 计数器解读,请参阅 GPU 分析参考文档。

Perfetto 核心概念

概念说明
Slice一段有计时的执行区间(函数调用、帧、渲染通道)。包含 ts(开始时间)、dur(时长)、name 和 track_id。
Track时间线轨道。线程轨道包含特定线程的片段;计数器轨道包含随时间变化的指标值。
Thread(utid)跟踪记录中的唯一线程 ID。联接时使用 utid(而非 tid)——tid 可能会被重复使用。
Process(upid)跟踪记录中的唯一进程 ID。联接时使用 upid(而非 pid)。
时间戳所有时间戳的单位均为纳秒。除以 1e6 可换算为毫秒,除以 1e9 可换算为秒。
Counter时间序列指标(GPU 利用率、时钟频率、温度)。存储在 counter 表中。
Args附加到片段上的键值元数据。通过 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 垂直同步对齐机制。表现为 PlayerLoop 开始处的空闲时间。这是正常且有意为之的——请勿将其标记为浪费时间。
  • 单通道多视图:在一个通道中渲染双眼画面。如果每帧出现两个渲染通道,应用可能正在使用多通道渲染(效率较低)。
  • 动态批处理:注意 SetPass 调用次数是否过高,这表明材质未被批处理。
  • IL2CPP 与 Mono:IL2CPP 构建在跟踪记录中使用不同的函数命名。请查找名称修饰后的 C++ 名称,而非 C# 方法名。
Unreal Engine
  • RHI 线程:Unreal 使用单独的 RHI(Render Hardware Interface)线程提交 GPU 命令。请检查此线程的驱动开销。
  • Forward 与 Deferred:Meta VR 上更推荐 Forward 渲染。Deferred 渲染的 GPU 开销明显更高。
  • Blueprint Tick:大量使用 Blueprint 会显示为 UObject::ProcessEvent。计数较高表明应将 Blueprint 转换为 C++。
  • Nativized Blueprints:在跟踪名称中会显示带有 __StaticExec 后缀的条目。

常见陷阱

  • 不要将 PhaseSync 或 xrWaitFrame 的空闲时间报告为性能问题——这些是有意设计的帧节奏机制。
  • surface#0 等 GPU 渲染通道名称缺乏描述性——请结合分辨率和 MSAA 级别判断其渲染内容。
  • 跟踪中的线程名称可能被截断。UnityMain 可能显示为 UnityMai 或类似形式。
  • 在 SQL 查询中联接与线程相关的表时,始终使用 utid(而非 tid)。
  • 时间戳的单位是纳秒。常见错误是将其当作微秒处理。
  • 计数器值是瞬时采样值,而非某个时间段内的平均值。

参考资料

有关特定主题的详细指南,请参阅:

  • 捕获跟踪 — 如何在 Meta VR 上捕获 Perfetto 跟踪
  • 分析跟踪 — 使用 SQL 查询逐步分析跟踪
  • GPU 分析 — 渲染通道分析、GPU 计数器和指标
  • 帧计时 — VR 帧标记、帧节奏和合成器计时
  • SQL 查询 — 用于常见分析任务的即用型 SQL 查询

评论

支持 Markdown