hz-simpleperf-debug について
Meta VR アプリ開発者向けの Simpleperf による CPU 分析スキルです。ハードウェアカウンターでボトルネックを分類し、ホットスポットとカーネル負荷を調べ、Perfetto の分析を補完します。
主な機能
- 01CPU・メモリ・I/O のボトルネック分類
- 02CPU サイクルのホットスポット記録
- 03スレッドごとのカーネル負荷測定
- 04Perfetto トレースとの併用
活用シーン
- 01VR アプリの主なボトルネックの特定
- 02CPU サイクルを多く消費する関数の発見
- 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 では、キャッシュミス、分岐予測ミス、命令スループットなど、Perfetto では確認できないハードウェアサイクルを CPU が「どこで」消費しているかを確認できます。
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 を付けてください。開発者モードを有効にして、Meta VR デバイスを USB で接続します。
クイックスタートのワークフロー
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 バウンド | 1 秒あたりのコンテキストスイッチ数が多い | ブロッキング 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 にはシェルアクセスが必要です。
adb shell simpleperfが失敗する場合は、開発者モードが有効で、USB デバッグが許可されていることを確認してください。 - サンプリング頻度と精度のトレードオフ。 サンプリング頻度が高い(>8000 Hz)と、モバイル SoC でワークロードに影響する可能性があります。デフォルトの 4000 Hz はバランスのよい設定です。
- 分類結果はある時点のスナップショットです。 アプリはゲームプレイ中は CPU 律速でも、シーンの読み込み中は I/O 律速になることがあります。最適化する具体的なシナリオをプロファイリングしてください。
参考資料
特定のトピックに関する詳細なガイドについては、以下を参照してください。
- ワークロードの分類 — PMU カウンターの解釈とボトルネックの特定
- CPU ホットスポット分析 — CPU サイクルプロファイルの記録と分析
- カーネルのオーバーヘッド — カーネルモードの CPU 使用率の測定と削減