平均 FPS
Android デバイスで高品質のゲーム エクスペリエンスを提供するには、スムーズで安定したフレームレートが不可欠です。ゲームのパフォーマンスを測定する際は、エクスペリエンスの基本的な理解を得るための ベースラインとして平均 FPS を測定する必要があります。優れたゲーム エクスペリエンスを実現するには、平均フレームレートが 60 FPS になるようにゲームを最適化する必要があります。
安定性のための P90 と P99 の FPS
平均 60 FPS でスムーズに動作するゲームでも、断続的な引っ掛かり、マイクロスタッター、予測不可能な入力遅延が発生し、プレーヤー エクスペリエンスが低下する可能性があります。
そのため、フレームの安定性は平均フレームレートの追跡と同じくらい重要です。 ここでは、P90 と P99 のフレームレート指標を、それぞれ一貫したベースラインとスタッター インジケーターとして測定する必要があります。これらの指標は、プレーヤー エクスペリエンスのスムーズさを最適化するために、パフォーマンスの「末尾」を捉えます。
指標
- 平均 FPS(ベースライン): この基本的な指標は、ゲームのパフォーマンスの一般的な ベースラインを示します。標準的なベンチマークですが、平均値の計算では断続的なフレームの低下やマイクロスタッターを検出できないため、プレーヤー エクスペリエンスを単独で表すには不十分です。
- P90 FPS(10% パーセンタイルでの一貫したベースライン): これは、フレームの 90% がこの一貫したベースラインを超えており、レンダリングに時間がかかったのは最も遅い 10% のフレームのみであることを示します。P90 フレームレートが高く、平均値に近い場合、セッションの大部分でゲームは一貫して良好に動作しています。
- P99 FPS(1% パーセンタイルでのスタッター インジケーター): これは、フレームの 99% がこのスタッター インジケーターを超えており、最も遅い 1% のフレームを特に分離していることを示します。この指標は、マイクロスタッター、アセット読み込みの遅延、目に見える引っ掛かりの原因となるアセットの多いレンダリングの急激な増加を捉えるために不可欠です。
例
平均 FPS を P90 指標と P99 指標と比較することで、ゲームの根本的な動作を正確に診断できます。
シナリオ 1: 最適な曲線(最適化されたゲーム)
- 平均: 60 FPS(16.6 ミリ秒)
- P90: 58 FPS(17.2 ミリ秒)
- P99: 52 FPS(19.2 ミリ秒)
- 分析: 指標は密にクラスタ化されています。ゲームは非常にスムーズで一貫性があります。マイクロスタッターはなく、最悪の 1% のフレームでも人間の目にはほとんど気づきません。
シナリオ 2: 負荷のボトルネック(CPU/GPU バウンド)
- 平均: 45 FPS(22.2 ミリ秒)
- P90: 40 FPS(25.0 ミリ秒)
- P99: 38 FPS(26.3 ミリ秒)
- 分析: 平均フレームレートは低いですが、一貫しています。P99 は平均値と比較して大幅に低下していません。これは、システムがグラフィック設定または解像度の制約によって基本的に過負荷になっていることを示しています。 ゲームはスタッターしているようには感じられませんが、動作が遅くなります。通常、グラフィック設定を下げると、これらの指標は均一にスケールアップします。
シナリオ 3: 不安定な 60 FPS(シェーダー コンパイル / アセット ストリーミング のスタッター)
- 平均: 60 FPS(16.6 ミリ秒)
- P90: 45 FPS(22.2 ミリ秒)
- P99: 15 FPS(66.6 ミリ秒)
- 分析: これは最悪のシナリオです。平均フレームレートは優れているように見えますが、P99 には重大な問題があります。P99 が 66.6 ミリ秒の場合、ゲームは一度に複数のフレームで完全にフリーズします。これは、通常、CPU のボトルネック、アセット ストリーミングの遅延(RAM やストレージの速度が遅いなど)、またはシェーダー コンパイルによる引っ掛かりが原因で発生する重大な外れ値を示しています。
測定
平均 FPS、P90、P99 を効果的に測定するには、Android
dumpsys surfaceflinger timestats コマンドを使用します。このツールは、レンダリングされているすべてのレイヤの平均 FPS と presentToPresent タイミング ヒストグラムを提供します。フレームの presentToPresent 時間は、現在のフレームと描画される前のフレームの間隔です。
ゲームのこれらの指標を収集して計算する手順は次のとおりです。
キャプチャを開始する: enable フラグと clear フラグを指定して次のコマンドを実行し、情報のキャプチャを開始します。
adb shell dumpsys SurfaceFlinger --timestats -clear -enable情報をダンプする: ゲームが十分にプレイされたら、dump フラグを指定してコマンドを再度実行し、情報を出力します。
adb shell dumpsys SurfaceFlinger --timestats -dumpレイヤでフィルタする: ダンプされた情報には、SurfaceFlinger によってレンダリングされたすべてのレイヤ のデータが含まれています。
layerName(layerName = SurfaceView[com.example.yourgame...] など)に基づいてフィルタして、ゲームに対応するセクションを見つける必要があります。layerName = SurfaceView[com.google.test/com.devrel.MainActivity]@0(BLAST)#132833平均 FPS を特定する: 各レイヤの平均 FPS は自動的に計算され、ダンプ出力に直接表示されます(averageFPS = 30.179 など)。
... averageFPS = 30.179 ...P90 と P99 の FPS を計算する: P90 指標と P99 指標を見つけるには、 ダンプで提供される totalFrames と
presentToPresentタイミング ヒストグラムを分析する必要があります。totalFrames = 1000 ... presentToPresent histogram is as below: 0ms=0 1ms=0 2ms=0 3ms=0 4ms=0 5ms=0 6ms=0 7ms=0 8ms=0 9ms=0 10ms=0 11ms=0 12ms=0 13ms=0 14ms=0 15ms=0 16ms=850 17ms=0 18ms=0 19ms=0 20ms=0 21ms=0 22ms=0 23ms=0 24ms=0 25ms=0 26ms=0 27ms=0 28ms=0 29ms=0 30ms=0 31ms=0 32ms=0 33ms=100 34ms=0 36ms=0 38ms=0 40ms=0 42ms=0 44ms=0 46ms=0 48ms=0 50ms=35 54ms=0 58ms=0 62ms=0 66ms=10 70ms=0 74ms=0 78ms=0 82ms=0 86ms=0 90ms=0 94ms=0 98ms=0 102ms=5 106ms=0 110ms=0 114ms=0 118ms=0 122ms=0 126ms=0 130ms=0 134ms=0 138ms=0 142ms=0 146ms=0 150ms=0 200ms=0 250ms=0 300ms=0 350ms=0 400ms=0 450ms=0 500ms=0 550ms=0 600ms=0 650ms=0 700ms=0 750ms=0 800ms=0 850ms=0 900ms=0 950ms=0 1000ms=0A. 概念的な例(累積分布表) ゲーム セッションで totalFrames のカウントが 1,000 と記録されたとします。P90 と P99 を見つけるには、累積フレーム数がそれぞれ 900 フレーム(90%)と 990 フレーム(99%)に達するミリ秒のしきい値を、最も低いミリ秒バケットから数えて計算します。
フレーム時間(ミリ秒) フレーム数(ヒストグラム) 累積フレーム数 パーセンタイルのステータス / 計算 16 ミリ秒 850 850 85.0% 33 ミリ秒 100 950 95.0%
(P90 の目標値 900 に到達しました。→ 1000/33 = 30.3 FPS)50 ミリ秒 35 985 98.5% 66 ミリ秒 10 995 99.5%
(P99 の目標値 990 に到達しました。→ 1000/66 = 15.1 FPS)102 ミリ秒 5 1,000 100% B. 実装ロジック(疑似コード) Python スクリプトまたはログパーサーを使用してこの分析を自動化する場合は、ヒストグラムから P90 値と P99 値を抽出するロジックを次のように実装できます。
# Define target thresholds based on total frame count p90_target = totalFrames * 0.90 p99_target = totalFrames * 0.99 cumulative_frames = 0 p90_fps = None p99_fps = None # Iterate through the parsed SurfaceFlinger histogram data (sorted by millisecond) for ms_bucket, frame_count in present_to_present_histogram: cumulative_frames += frame_count # Capture P90 when cumulative frames cross the 90% threshold if p90_fps is None and cumulative_frames >= p90_target: p90_fps = 1000 / ms_bucket # Capture P99 when cumulative frames cross the 99% threshold if p99_fps is None and cumulative_frames >= p99_target: p99_fps = 1000 / ms_bucket break # Optimization: stop iterating once both targets are foundキャプチャを停止する: 必要な情報をすべて収集したら、 disable フラグを使用して timestats を無効にする必要があります。
adb shell dumpsys SurfaceFlinger --timestats -disable
速度の遅いセッション
速度の遅いセッションは、広範囲にわたる実際のパフォーマンスの問題を特定します。25% を超えるフレームがしきい値(20 FPS など)を下回る場合、セッションは「速度が遅い」と見なされます。 この指標はビルドの重大な問題を特定するのに役立ちますが、この指標だけでは高品質で持続可能なエクスペリエンスを保証することはできません。ゲームは速度の遅いセッションのしきい値を回避できますが、スムーズな 60 FPS エクスペリエンスを損なうマイクロスタッターが発生する可能性があります。
どちらもフレーム時間から派生していますが、「速度の遅いセッション」と「フレームレート」は異なる役割を果たします。平均 FPS、P90 FPS、P99 FPS の指標は、パフォーマンスの品質と持続可能性を測定し、速度の遅いセッションの指標では見落とされる可能性のある瞬間的な低下や一貫性のないペースを検出します。
まとめ
パフォーマンスの最適化を成功させるには、包括的な戦略が必要です。 デベロッパーは、速度の遅いセッションを主要なレーダーとして使用して、パフォーマンスの重大な低下を捉え、平均 FPS、P90、P99 を調べて根本原因を診断し、ゲームプレイの実際のスムーズさを確認する必要があります。これらの指標を統合することで、アプリケーションが一貫して持続可能で優れたユーザー エクスペリエンスを提供できるようになります。
参考情報
高度なプロファイリング手法、Frame Pacing API の実装、エンジン固有の最適化戦略について詳しくは、Android デベロッパーの公式ドキュメントをご覧ください。
- Android Vitals: 速度の遅いセッション: Google Play が、ユーザー エクスペリエンスに直接影響する、レンダリングの遅延が続く期間を測定してレポートする方法について説明します。「速度の遅いセッション」は、25% を超えるフレームの速度が遅い(50 ミリ秒以上、20 FPS 相当)ユーザー セッションとして定義されます。
- Android デベロッパー: ゲームのパフォーマンスを最適化する: Android ゲームの最適化に関する 中心的なハブをご覧ください。この包括的なガイドでは、ゲームの全体的なパフォーマンスを最大限に高めるためのベスト プラクティスとプロファイリング ツール(AGI や Perfetto など)について説明します。