关于 hz-simpleperf-debug
为 Meta VR 应用开发者提供基于 Simpleperf 的 CPU 性能分析流程,通过硬件计数器分类瓶颈、定位热点并测量内核开销,补充 Perfetto 分析。
主要功能
- 01分类 CPU、内存与 I/O 瓶颈
- 02采集 CPU 周期热点
- 03按线程测量内核开销
- 04结合 Perfetto 定位性能问题
适用场景
- 01判断 VR 应用的主要性能瓶颈
- 02查找消耗 CPU 周期最多的函数
- 03检查线程的内核态开销
- 04将硬件计数器结果与 Perfetto 轨迹关联
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ meta-quest/ agentic-tools --skill hz-simpleperf-debug安装后在 Claude Code 中输入/hz-simpleperf-debug确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/cpu-hotspot-analysis.mdkernel-overhead.mdworkload-classification.md详细介绍
Simpleperf 调试技能
适用场景
当你需要在 Meta VR 设备上获取硬件级 CPU 性能洞察时,请使用此技能:
- 判断应用是受 CPU、内存还是 I/O 限制
- 找出消耗周期最多的 CPU 热点函数
- 测量每个线程的内核与用户空间 CPU 开销
- 识别缓存抖动或分支预测问题
- 使用硬件 PMU 计数器数据补充 Perfetto 跟踪分析
此技能可与 hz-perfetto-debug 互为补充。Perfetto 展示应用随时间的运行情况。Simpleperf 展示 CPU 将硬件周期花在了哪里——缓存未命中、分支预测错误,以及 Perfetto 无法观测到的指令吞吐量。
VR 性能背景
Meta VR 设备搭载移动 ARM SoC,受严格的散热和功耗预算限制。受 CPU 限制的应用会在以下帧时间预算下出现掉帧:
| 刷新率 | CPU 帧时间预算 | 备注 |
|---|---|---|
| 120 Hz | 8.3 ms | 预算紧张——Simpleperf 对查找热点至关重要 |
| 90 Hz | 11.1 ms | 大多数应用的默认目标 |
| 72 Hz | 13.9 ms | 较重应用的回退选项 |
Simpleperf 的硬件计数器可以揭示软件跟踪无法发现的瓶颈。
metavr 设置
Simpleperf 性能分析由 metavr CLI 驱动——将独立二进制文件安装到 PATH 中(参见 metavr-cli 技能),或使用 npx 调用而无需安装:
metavr --version
以下示例使用裸命令 metavr;如果你使用 npm 发行版,请在命令前加上 npx -y。通过 USB 连接 Meta VR 设备,并启用开发者模式。
快速入门工作流
1. 分类工作负载
优化前,先确定瓶颈类型:
# Classify the foreground app's workload (10-second sample)
metavr perf simpleperf classify
# Target a specific app
metavr perf simpleperf classify --app com.example.myapp
# Custom duration
metavr perf simpleperf classify --duration 15
该命令会返回分类结果及依据:
| 分类 | 指标 | 优化策略 |
|---|---|---|
| 受 CPU 限制 | IPC 高,停顿率低 | 优化算法、减少绘制调用、批处理工作 |
| 受内存限制 | 停顿率高(stalled-cycles-backend / cpu-cycles) | 减少缓存未命中、改善数据局部性、缩小工作集 |
| 受 I/O 限制 | 每秒上下文切换次数高 | 减少阻塞式 I/O、使用异步操作、尽量减少线程争用 |
2. 记录 CPU 热点
采集 CPU 周期性能分析,找出开销最大的函数:
# Record CPU hotspots for the foreground app
metavr perf simpleperf record
# Custom frequency and duration
metavr perf simpleperf record --frequency 4000 --duration 10
# Target a specific app
metavr perf simpleperf record --app com.example.myapp
录制会按指定频率(默认 4000 Hz)对 CPU 周期进行采样,并生成性能分析结果,显示哪些函数消耗的 CPU 时间最多。
3. 测量内核开销
确定每个线程的 CPU 时间分别花在内核和用户空间的比例:
# Measure kernel overhead for the foreground app
metavr perf simpleperf kernel-overhead
# Custom duration
metavr perf simpleperf kernel-overhead --app com.example.myapp --duration 10
该命令会返回每个线程在用户模式和内核模式下的 CPU 周期明细。线程的内核开销较高(>20%)可能表明存在以下情况:
- 系统调用过多(文件 I/O、内存分配)
- 驱动开销(GPU 命令提交、传感器访问)
- 内核同步原语中的锁争用
分析工作流
步骤 1:先分类
始终从分类开始,以免把时间浪费在优化错误的对象上。
metavr perf simpleperf classify --app com.example.myapp --duration 10
根据结果采取行动的决策树:
- 受 CPU 限制 → 记录热点(步骤 2a),查看排名靠前的函数
- 受内存限制 → 使用缓存未命中事件进行记录,检查数据访问模式
- 受 I/O 限制 → 检查内核开销,并在 Perfetto 中查看线程争用情况
步骤 2a:受 CPU 限制的应用——查找热点
metavr perf simpleperf record --app com.example.myapp --duration 10
查看按 CPU 周期消耗量排列的顶级函数。常见的 VR 热点包括:
| 函数模式 | 可能原因 | 修复方法 |
|---|---|---|
Physics.* / PhysX | 物理模拟过于复杂 | 减少碰撞体数量、简化网格、增大固定时间步长 |
Render* / Draw* | 绘制调用过多 | 批处理材质、使用 GPU 实例化、减少不同材质的数量 |
GC_* / gc_alloc | 垃圾回收压力 | 使用对象池、避免每帧分配 |
memcpy / memmove | 大量数据复制 | 使用引用、减小缓冲区、避免不必要的复制 |
LZ4_* / compress | 资源解压 | 预先解压、使用更轻量的压缩方式、缓存结果 |
步骤 2b:内存受限的应用 — 检查缓存行为
如果分类结果显示受内存限制,问题很可能是缓存未命中或内存带宽不足:
- 工作集过大,导致 L1/L2 缓存频繁抖动
- 随机访问模式使预取器无法发挥作用
- 相邻缓存行上的线程之间发生伪共享
使用 Perfetto hz-perfetto-debug 将内存受限区域与特定代码路径关联起来。
步骤 3:测量内核开销
metavr perf simpleperf kernel-overhead --app com.example.myapp
按线程解读结果:
| 线程 | 预期内核占比 | 内核占比过高表示 |
|---|---|---|
| 主线程/游戏线程 | < 5% | 文件 I/O、日志记录或内存分配过多 |
| 渲染线程 | 5-15% | 属于正常范围(GPU 驱动开销)。>20% = 驱动问题 |
| 工作线程 | < 5% | 线程同步开销 |
| 音频线程 | < 10% | 对于音频 HAL 调用而言属于正常范围 |
步骤 4:结合 Perfetto 分析
Simpleperf 可以告诉你周期消耗在哪里。Perfetto 可以告诉你何时消耗以及所处的上下文。请结合使用:
- Simpleperf 分类结果揭示瓶颈类型
- Simpleperf 热点记录找出开销较大的函数
- Perfetto 跟踪(
metavr perf capture)显示这些函数相对于帧边界的运行时间 - 使用
metavr perf query将函数耗时与帧丢失关联起来
常见问题
- 不要在热降频状态下进行性能分析。 录制前先让设备冷却下来——降频会扭曲周期计数。先使用
metavr device info检查热状态。 - 采样时长很重要。 短时间录制(<5s)可能无法捕捉到有代表性的行为。分类时至少录制 10 秒。
- simpleperf 需要 shell 访问权限。 如果
adb shell simpleperf执行失败,请确保已启用开发者模式并授权 USB 调试。 - 频率与准确度之间需要权衡。 较高的采样频率(>8000 Hz)可能会干扰移动 SoC 上的工作负载。默认的 4000 Hz 是较好的平衡点。
- 分类结果只是某一时刻的快照。 应用在游戏过程中可能受 CPU 限制,而在场景加载过程中可能受 I/O 限制。请针对要优化的特定场景进行性能分析。
参考资料
有关特定主题的详细指南,请参阅: