WWDC Quick Look 💓 By SwiftGGTeam
Metal ゲームのパフォーマンス問題を見つけて修正する

Metal ゲームのパフォーマンス問題を見つけて修正する

元の動画を見る

ハイライト

Metal パフォーマンストレースには、metalperftrace コマンドラインツールと StateReporting API が追加されました。これにより、数時間にわたるゲームセッションのパフォーマンスデータを収集、分析でき、開発者はフレームレート低下の根本原因をすばやく特定できます。

主要内容

ゲーム最適化は、さまざまなデバイスでテストし、データを収集し、結果を分析し、問題を特定して修正し、また繰り返すという循環プロセスです。手順としては普通に聞こえますが、実際の運用には痛点があります。

プレイヤーは数分ではなく、何時間もゲームを遊びます。その数時間の間に、状況は絶えず変化します。デバイスが発熱し、温度制御によるクロック低下が起き、プレイヤーが画質設定を変え、ステージを切り替え、別のシーンへ入ります。短時間のテストだけでは、長時間プレイで初めて現れるパフォーマンス問題を見落としがちです。

Metal Performance HUD は FPS、メモリ、フレーム間隔などの指標をすばやく確認できますが、データを保存できません。数時間プレイした後では、フレームレートがどの時点で落ちたかを正確に思い出すのは困難です。

Apple の解決策は、CPU、GPU、FPS、メモリなどを含む Metal パフォーマンスデータをシステムが継続的に記録することです。データは数日間保存できます。ゲーム終了後、過去にさかのぼって数時間分の完全なパフォーマンスデータを収集できます。

macOS では metalperftrace コマンドラインツールで収集します。iOS では、Developer Settings で Performance Trace を有効にし、Control Center のボタンからワンタップで収集します。

ただし、データを得ることは最初の一歩にすぎません。ある時点で FPS が 26 に落ちたと分かっても、そのときゲームが何をしていたかは分かりません。どのステージだったのか、画質設定は何だったのか、ネットワーク状況はどうだったのか。

ここで Context(文脈)が重要になります。Apple は新しい StateReporting API を導入しました。これにより、ゲームは任意の時点での動作や状態を記述し、その状態情報をパフォーマンスデータと結び付けられます。

詳細

Metal Performance HUD の基本

(00:29)

Metal Performance HUD は、ゲーム内容の上に FPS、メモリ使用量、フレーム間隔などのパフォーマンス指標を重ねて表示します。表示する指標をカスタマイズする設定パネルがあり、各指標を個別にオンオフしたり、プリセットを選んだりできます。

HUD は開発中にパフォーマンス傾向をすばやく見るには有用ですが、長期保存機能はありません。

パフォーマンスデータをさかのぼって収集する

(04:40)

システムは Metal パフォーマンスとリソース使用データを継続的に記録します。集約指標に加え、任意で CPU、GPU、FPS、Memory のフレーム単位指標も含められます。これらのデータは効率的に保存され、数日間保持できます。

macOS での収集方法

(05:00)

macOS 27 では新しい metalperftrace コマンドラインツールが提供されます。

# 過去 5 時間のデータを収集する
metalperftrace collect /tmp --last 5h

# 出力
# Metal パフォーマンストレースの収集先: /tmp
# /tmp/MetalPerfTrace_20260401_094100_to_144100.atrc

# または明示的な時間範囲を指定する
metalperftrace collect /tmp \
  --start 2026-04-01T09:41:00 \
  --end 2026-04-01T12:41:00

重要な点:

  • collect はサブコマンドで、出力ディレクトリを指定します。
  • --last は時間から日数までの範囲をサポートします。
  • --start--end で正確な時間範囲を指定することもできます。
  • 出力は .atrc 形式の trace ファイルです。

iOS での収集方法

(05:39)

iOS では一度だけデバイス設定が必要です。

  1. Developer Mode をオンにし、Developer Settings を開きます。
  2. Performance Trace を有効にします。
  3. Lookback Collection を選び、さかのぼる時間を設定します。
  4. Control Center に Performance Trace ボタンを追加します。

設定後は通常どおりゲームをプレイします。ゲーム終了後、Control Center から Performance Trace ボタンをタップすると、デバイスが指定時間分のデータを自動で収集、処理します。処理が完了すると通知が届き、trace ファイルが利用可能なファイル一覧に現れます。Mac に転送して分析できます。

trace データを分析する

(06:49)

metalperftrace overview を使う

(07:02)

metalperftrace overview /Data/MyGameTrace.atrc

# [Modern Renderer pid:13833]
# Mem: 2146.1 MiB (2343.9 Peak, 1199.4 Metal)
# Total CPU Time: 2417.601s (33.17% Sys, 66.83% User)
# Instructions: 9944836683668 (5.75% P, 94.25% E)
# Cycles: 5176430469224 (4.45% P, 95.55% E)
# Disk Reads / Writes: 317.37 / 0.04 MiB (Logical Write 0.04)
# Layer 0x729293000 (3456x2104) Interval 300.065s Active 300.065s
#   59.7 FPS  17735 Frames  188 Skipped
#   Frame Time avg: 16.74ms min: 8.33 max: 125.00 stddev: 3.70
#   CPU Begin-to-Present avg: 3.99ms min: 1.40 max: 94.37 stddev: 1.80
#   On-GPU Time avg: 13.39ms min: 5.24 max: 37.57 stddev: 1.43
#   Next Drawable Wait avg: 0.26ms min: 0.00 max: 91.08 stddev: 1.75
#   Shader Compilation Time: 0.000s (Total: 0, Cached: 18)

重要な点:

  • レポートは、メモリ、CPU、ディスクなどのリソース使用統計と、Metal パフォーマンス指標の2部構成です。
  • 各 layer には FPS、フレーム数、スキップされたフレーム数が表示されます。
  • フレーム時間には平均、最小、最大、標準偏差が表示されます。
  • GPU 時間と CPU の begin-to-present 時間は重要な指標です。

trace に複数プロセスが含まれる場合、predicate で特定プロセスを絞り込むか、--json で構造化データを出力してスクリプトで処理できます。

JSON 出力

(07:58)

metalperftrace overview /Data/MyGameTrace.atrc --json --predicate 'process == "MyGame"'

重要な点:

  • --json は機械可読な構造化出力を生成します。
  • 回帰テストや、AI によるパフォーマンス問題の自動分析に利用できます。
  • --predicate で特定プロセスを絞り込めます。

Instruments で可視化する

(08:29)

Instruments は trace ファイルを開いて可視化分析できます。データは時系列で描画され、システムが自動的に評価して異常値をハイライトします。通常範囲から外れた指標は別の色でマークされます。

タイムライン上で区間を選択すると、Instruments がその区間の統計データを自動集計します。

StateReporting API

(09:56)

パフォーマンス問題を特定するには、その瞬間のゲーム状態を知る必要があります。StateReporting API を使うと、ゲームの動作と状態変化を記述できます。

中核概念

(10:15)

  1. Domain(ドメイン):特定機能領域の有限状態機械です。たとえばプレイヤー進行を追跡するレベルドメインです。
  2. State(状態):各ドメインは同時に1つの状態だけを取れます。
  3. Label(ラベル):状態の名前です。例:「レベル 1」。
  4. Stable Metadata(安定メタデータ):状態の構造化情報を含む不変の辞書です。
  5. Volatile Metadata(可変メタデータ):状態内で変化する値です。例:プレイヤーの体力。

コード例

(12:10)

#import <StateReporting/StateReporting.h>

// ドメインを作成し reporter を取得する
NSString *domain = @"com.mygame.level";
SRStateReporter *reporter = [SRStateReporter reporterForDomain:domain];

// 状態遷移を報告する
[reporter reportTransitionToStateLabel:@"レベル 1"
                        stableMetadata:nil
                      volatileMetadata:nil];

// 安定メタデータ付きの遷移
[reporter reportTransitionToStateLabel:@"レベル 1"
                        stableMetadata:@{ @"id": @1001 }
                      volatileMetadata:nil];

// 状態を変えずに可変メタデータを更新する
[reporter reportVolatileMetadataUpdate:@{ @"health": @100 }];

重要な点:

  • ドメイン名には通常、逆 DNS 文字列を使います。
  • reporterForDomain: はドメインの状態 reporter を取得します。
  • reportTransitionToStateLabel は状態遷移を報告します。
  • stableMetadata は状態の不変情報を含みます。
  • reportVolatileMetadataUpdate は状態を遷移させずに可変データを更新します。

StateReporting とツール統合

Metal Performance HUD 統合

(13:00)

Metal Performance HUD の指標設定タブに、状態ドメインが一覧表示されます。有効にすると、オーバーレイにラベル、安定メタデータ、可変メタデータが表示されます。

metalperftrace 統合

(13:42)

trace に状態遷移が含まれる場合、metalperftrace overview はドメイン一覧、遷移回数、最後に分かっている状態を表示します。

# 完全な状態遷移を表示する
metalperftrace overview /Data/MyGameTrace.atrc --include-state-transitions

# [States]
# com.mygame.graphics
#   高 (30.59%, 14.996s)  raytracing: 1  shadow: ultra
#   中 (69.38%, 34.012s)  raytracing: 0  shadow: medium
# com.mygame.level
#   レベル 1 (20.47%, 10.033s)  biome: forest   id: 1001
#   レベル 2 (79.53%, 38.991s)  biome: volcano  id: 1002

重要な点:

  • --include-state-transitions は完全な状態一覧とタイムスタンプを出力します。
  • 各状態の継続時間と比率が表示されます。
  • 安定メタデータも含まれます。

状態ごとに指標を集計する

(14:15)

# すべてのドメインを集計する
metalperftrace overview /Data/MyGameTrace.atrc --aggregate

# 特定ドメインを集計する
metalperftrace overview /Data/MyGameTrace.atrc --aggregate \
  --domain com.mygame.graphics

# 特定の状態ラベルを集計する
metalperftrace overview /Data/MyGameTrace.atrc --aggregate \
  --domain com.mygame.graphics \
  --state-label "高"

重要な点:

  • --aggregate は状態ごとに指標を自動集計します。
  • ドメインや具体的な状態ラベルを指定できます。
  • レポートには状態のアクティブ時間と重複状態が表示されます。

Instruments 統合

(15:02)

Instruments は Points of Interest instrument の一部として、各ドメインに1つのトラックを作成します。各トラックには状態遷移と可変更新が描画され、文脈を理解しやすくなります。

単一の状態を選択すると、サイドバーで安定メタデータと可変メタデータを含む詳細情報を確認できます。

ベストプラクティス

(16:17)

  1. ドメインと状態を慎重に設計する:各ドメインは概念的に直交しているべきです。1つのドメインで多すぎる次元を表さないでください。
  2. 状態遷移の頻度を制限する:StateReporting は長時間パフォーマンス分析のためのもので、高頻度な状態変化向けではありません。遷移頻度はユーザー操作の頻度以下に抑えるべきです。
  3. 状態の正しさを検証する:Metal Performance HUD と Instruments を使って、遷移が期待どおりか確認し、境界ケースをチェックします。

リリース後監視:MetricKit

(17:54)

MetricKit は2種類のデータを提供します。指標と診断です。バックグラウンドで継続的にデータを収集し、毎日ゲームプロセスへレポートを配信します。

macOS と iOS 27 では、MetricKit に Metal フレームレート情報と、StateReporting の状態ごとに集計されたフレームレートデータが追加されます。

レポートには全体平均フレームレート、時間、フレーム数が含まれ、level domain 内の状態ごとにフレームレート情報をグループ化して表示することもできます。

より深い分析ツール

(15:44)

十分な文脈が得られたら、次のツールでさらに深く分析できます。

  • Instruments の Metal System Trace テンプレート:詳細な CPU と GPU のスケジューリングデータを捕捉します。
  • Xcode の Metal Debugger:単一フレームを捕捉してプロファイルします。

重要な示唆

  1. レベル読み込みパフォーマンス分析器:StateReporting でレベル状態と読み込み段階を報告し、metalperftrace で各レベルのフレームレートパターンを分析します。どのレベルにパフォーマンス問題があるか、それが特定のシーン要素に関係するかを見つけます。

  2. 画質設定レコメンドシステム:影品質、レイトレーシングなどの画質設定とフレームレートの関係を追跡します。--aggregate で状態ごとに指標を集計し、どの設定組み合わせがフレーム低下を引き起こすかを見つけ、デバイスごとに最適設定を推奨します。

  3. プレイヤー行動ヒートマップ:可変メタデータでプレイヤー位置、戦闘状態などを追跡し、どのエリアや活動がパフォーマンス低下を引き起こすかを分析します。MetricKit の現場データと組み合わせて、多くのプレイヤーが遭遇するパフォーマンス問題領域を見つけます。

  4. 自動パフォーマンス回帰テストmetalperftrace の JSON 出力を CI/CD に統合し、新バージョンのフレームレートやメモリが異常かどうかを自動検出します。AI agent で JSON データを分析し、潜在的な問題に印を付けます。

  5. 熱スロットリング警告:デバイス状態と温度状態を追跡し、フレームレート低下と熱スロットリングイベントを関連付けます。異なる温度状態でゲームがどう動くかを理解し、発熱時のパフォーマンスを最適化します。

関連セッション

コメント

GitHub Issues · utterances