Version: 2022.1
言語: 日本語
動的解像度
ディープラーニングスーパーサンプリング

FrameTimingManager

FrameTimingManager は、アプリケーションの個々のフレーム中のパフォーマンスに関する詳細なタイミングデータを取得する API です。このデータを使用してフレームを評価することで、アプリケーションがパフォーマンス目標に達しない理由を理解することができます。

以下のような場合に FrameTimingManager を使用してください。

フレームタイミングは、プロファイラー からのデータを置き換えるものではありません。アプリケーションを高レベルでプロファイリングした後に、FrameTimingManager を使用して特定の詳細を調査してください。FrameTimingManager は、データを記録する時にパフォーマンスを低下させるため、アプリケーションのパフォーマンスを正確に測定することはできません。

FrameTimingManager を有効にする方法

ヒント: FrameTimingManager は、開発用プレイヤービルドでは常にアクティブです。

リリースビルド用に Unity エディターで FrameTimingManageer を有効にするには、以下の手順に従ってください。

  1. Edit > Project Settings > Player を開きます。
  2. Other Settings 内で Rendering という見出しを見つけてください。
  3. Frame Timing Stats プロパティを有効にしてください。

OpenGL プラットフォームを使用している場合は、GPU 使用率を測定するために OpenGL: Profiler GPU Recorders プロパティも有効にする必要があります。これは以下の手順で行えます。

  1. Edit > Project > Settings > Player を開きます。
  2. Other Settings 内で Rendering という見出しを見つけてください。
  3. OpenGL: Profiler GPU プロパティを有効にします。

ノート: バージョン 2021.2 以前の Unity では、OpenGL Profiler GPU RecorderFrame Timing Stats プロパティを無効にするため、これらを併用できません。

FrameTimingManager の使用方法

FrameTimingManager の記録するデータにアクセスするには、以下のいずれかの方法を使用してください。

カスタムプロファイラーモジュールにフレーム時間データを表示する

以下の手順で、カスタムプロファイラーモジュールにフレームタイミングデータを表示できます。

  1. カスタムプロファイラーモジュールの作成 の手順に従ってカスタムプロファイラーモジュールを作成します。
  2. Profiler Module Editor ウィンドウで、カスタムモジュールを選択します。
  3. Available Counters パネルで Unity を選択します。
  4. Render を選択して、メモリ使用量に関連するプロファイラーカウンター (FrameTimingStats プロパティによって有効になるものを含む) が含まれたブメニューを開きます。サブメニュー内の関連カウンターをクリックすることで、それをカスタムモジュールに追加できます。

以下の表は、Frame Timing Stats を有効にすると使用可能になる各カウンターの役割を説明したものです。

測定項目 説明 
CPU Total Frame Time (ms) CPU フレーム時間の合計 (ミリ秒単位) です。Unity はこれを、2 つのフレームの終了時点と終了時点の間の時間として (オーバーヘッドやフレーム間の待機時間も含めて) 計算します。
CPU Main Thread Frame Time (ms) フレームの開始から、メインスレッドがそのフレーム中に実行した作業を終了するまでの時間 (ミリ秒単位) です。
CPU Main Thread Present Wait Time (ms) フレーム中で Present() を待機するのに費やされた CPU 時間です。
CPU Render Thread Frame Time (ms) Render Thread での処理の開始から、Unity が Present() 関数を呼び出すまでの時間 (ミリ秒単位) です。
GPU Frame Time (ms) GPU の、単一のフレームのレンダリングの開始時間と終了時間の差 (ミリ秒単位) です。

FrameTimingManager C# API からタイムスタンプデータを取得する

FrameTimingManager API を使用してタイムスタンプ情報にアクセスできます。FrameTimingManager は、各変数に、フレーム中で特定のイベントが発生する時間を記録します。

以下の表は、この API を通して利用可能な値を、Unity がフレーム中に実行する順番で示したものです。

プロパティ 説明 
frameStartTimestamp フレームが開始する CPU 時間です。
firstSubmitTimestamp Unity がこのフレーム中で最初のジョブを GPU に投入する CPU 時間です。
cpuTimePresentCalled Unity が現在のフレーム用に Present() 関数を呼び出す CPU 時間です。
cpuTimeFrameComplete GPU がフレームのレンダリングを終了して CPU に割り込む CPU 時間です。

特定のプロファイラーカウンターでデータを記録する

FrameTimingManager の C# API の代わりに ProfilerRecorder API を使用して FrameTimingManager の値を読み取ることができます。この利点は、ProfilerRecorder API を使用すると、特定のカウンターにレコーダーが設定した時にのみ FrameTimingManager が値を記録することです。この動作のおかげで、どのカウンターがデータを収集するか制御できるようになるため、FrameTimingManager がパフォーマンスに与える影響を抑えられます。

以下の例は、ProfilerRecordAPI を使用して CPU Main Thread Frame Time 変数のみを追跡する方法を示しています。


using Unity.Profiling;

using UnityEngine;

public class ExampleScript : MonoBehaviour

{

    string statsText;

    ProfilerRecorder mainThreadTimeRecorder;

    void OnEnable()

    {
        mainThreadTimeRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Internal, "CPU Main Thread Frame Time");
    }

    void OnDisable()

    {
        mainThreadTimeRecorder.Dispose();
    }

    void Update()

    {

        var frameTime = mainThreadTimeRecorder.LastValue;

        // Your code logic here

    }
}

FrameTimingManager の機能について

FrameTimingManager は、4 フレーム分の固定された遅延を含んだ結果を提供します。これは、タイミングの結果が各フレームの終了時にすぐに得られないからで、このために FrameTimingManager はフレームの CPU および GPU データを取得する前に待機するからです。

この遅延は、正確なタイミングの結果を保証するものではありません。なぜなら、GPU が結果を返すために使用可能なリソースを持っていなかったり、正しく結果を返せない可能性があるからです。

FrameTimingManger は、以下のような特定の状況下では、FrameTimeComplete タイムスタンプの生成方法を変更します。

  • GPU が GPU タイムスタンプをサポートしている場合は、GPU が FrameTimeComplete タイムスタンプを提供します。
  • GPU が GPU タイムスタンプをサポートしておらず GPU Time を返す場合は、FrameTimingManager は gpuFrameTime の値を計算します。この値は、レポートされた GPU Time と FirstSubmitTimestamp の値の合計です。
  • GPU が GPU タイムスタンプをサポートしておらず、GPU Timeを返さない場合は、FrameTimingManager は PresentTimestamp の値を FrameTimeComplete の値として設定します。

タイルベースのディファードレンダリング GPU での不正確性

Apple デバイスの Metal GPU など、タイルベースのディファードレンダリングアーキテクチャを使用する GPU では、レポートされる GPU 時間が、レポートされるフレーム時間よりも大きくなる可能性があります。

これは、GPU にかかる負荷が高い時や、GPU パイプラインが満杯の時に発生する可能性があります。このような場合、GPU は、一部のレンダリングフェーズの実行を延期する場合があります。FrameTimingManager はフレームのレンダリングの開始と終了の間の時間を測定するため、フェー ズ間にギャップがあると、レポートされる GPU 時間が増大します。

以下の例では、GPU が Vertex キューから Fragment キューにジョブを渡すため、使用可能な GPU リソースがありません。このため、GPU のグラフィックス API は、次のフェーズの実行を延期します。このような場合、GPU の時間測定にフェーズの処理時間とその間のギャップが含まれることになります。その結果、FrameTimingManager が、予想よりも高い GPU 時間測定値をレポートします。

レポートされた GPU 時間の不一致が Metal API でどのように起こり得るかを示す図
レポートされた GPU 時間の不一致が Metal API でどのように起こり得るかを示す図

プラットフォームのサポート

プロパティ 説明  サポート コメント
Windows DirectX 11 あり
DirectX 12 あり
OpenGL あり
Vulkan あり
macOS Metal あり タイルベースのディファードレンダリング GPU の動作により、総フレーム時間よりも大きな GPU 時間測定値がレポートされる可能性があります。
Linux OpenGL 場合によって推奨 GPU 時間計測をサポートしていません。
Vulkan あり
Android OpenGL ES あり
Vulkan あり
iOS Metal あり タイルベースのディファードレンダリング GPU の動作により、総フレーム時間よりも大きな GPU 時間測定値がレポートされる可能性があります。
tvOS Metal あり タイルベースのディファードレンダリング GPU の動作により、総フレーム時間よりも大きな GPU 時間測定値がレポートされる可能性があります。
WebGL WebGL 場合によって推奨 GPU 時間計測をサポートしていません。

その他の参考資料

動的解像度
ディープラーニングスーパーサンプリング