FrameTimingManager は、アプリケーションの個々のフレーム中のパフォーマンスに関する詳細なタイミングデータを取得する API です。このデータを使用してフレームを評価することで、アプリケーションがパフォーマンス目標に達しない理由を理解することができます。
以下のような場合に FrameTimingManager を使用してください。
フレームタイミングは、プロファイラー からのデータを置き換えるものではありません。アプリケーションを高レベルでプロファイリングした後に、FrameTimingManager を使用して特定の詳細を調査してください。FrameTimingManager は、データを記録する時にパフォーマンスを低下させるため、アプリケーションのパフォーマンスを正確に測定することはできません。
ヒント: FrameTimingManager は、開発用プレイヤービルドでは常にアクティブです。
リリースビルド用に Unity エディターで FrameTimingManageer を有効にするには、以下の手順に従ってください。
OpenGL プラットフォームを使用している場合は、GPU 使用率を測定するために OpenGL: Profiler GPU Recorders プロパティも有効にする必要があります。これは以下の手順で行えます。
ノート: バージョン 2021.2 以前の Unity では、OpenGL Profiler GPU Recorder が Frame Timing Stats プロパティを無効にするため、これらを併用できません。
FrameTimingManager の記録するデータにアクセスするには、以下のいずれかの方法を使用してください。
以下の手順で、カスタムプロファイラーモジュールにフレームタイミングデータを表示できます。
以下の表は、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 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 は、4 フレーム分の固定された遅延を含んだ結果を提供します。これは、タイミングの結果が各フレームの終了時にすぐに得られないからで、このために FrameTimingManager はフレームの CPU および GPU データを取得する前に待機するからです。
この遅延は、正確なタイミングの結果を保証するものではありません。なぜなら、GPU が結果を返すために使用可能なリソースを持っていなかったり、正しく結果を返せない可能性があるからです。
FrameTimingManger は、以下のような特定の状況下では、FrameTimeComplete タイムスタンプの生成方法を変更します。
Apple デバイスの Metal GPU など、タイルベースのディファードレンダリングアーキテクチャを使用する GPU では、レポートされる GPU 時間が、レポートされるフレーム時間よりも大きくなる可能性があります。
これは、GPU にかかる負荷が高い時や、GPU パイプラインが満杯の時に発生する可能性があります。このような場合、GPU は、一部のレンダリングフェーズの実行を延期する場合があります。FrameTimingManager はフレームのレンダリングの開始と終了の間の時間を測定するため、フェー ズ間にギャップがあると、レポートされる GPU 時間が増大します。
以下の例では、GPU が Vertex キューから Fragment キューにジョブを渡すため、使用可能な GPU リソースがありません。このため、GPU のグラフィックス API は、次のフェーズの実行を延期します。このような場合、GPU の時間測定にフェーズの処理時間とその間のギャップが含まれることになります。その結果、FrameTimingManager が、予想よりも高い GPU 時間測定値をレポートします。
プロパティ | 説明 | サポート | コメント |
---|---|---|---|
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 時間計測をサポートしていません。 |
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.