Unity のコードは プロファイラーマーカー を使用してインストルメント化されており、アプリケーションで何に時間がかかっているかを知ることができます。以下の表は、ビルトインマーカーの一部のリストです。
メインスレッドの基本マーカーは、アプリケーションに費やされた時間と、Unity エディターやプロファイラーのアクティビティに費やされた時間を明確に区別します。また、これらのマーカーを ProfilerRecorder API とともに使用してメインスレッドのフレームのタイミングを取得したり、 FrameTimingManager API を使用してランタイムにフレームに関する高度な統計情報を取得したりすることもできます。
また、レンダリングプロファイラーの各カウンター、CPU Main Thread Frame Time、 CPU Render Thread Frame Time、CPU Total Frame Time を使用して、アプリケーションの CPU 使用量のタイミングに関する高度な情報を取得することもできます。詳細は、レンダリングプロファイラーカウンターのリファレンス を参照してください。
| マーカー | 説明 |
|---|---|
| PlayerLoop | アプリケーションのメインループから発生するすべてのサンプルが含まれます。プレイヤーがエディターでアクティブな再生モードで実行されているときに、再生モードではなく エディターをターゲットにする 場合、PlayerLoop のサンプルは EditorLoop の下にネストされます。 |
|
EditorLoop (エディター専用マーカー) |
エディターのメインループから発生するすべてのサンプルが含まれます。これは、エディターでプレイヤーをプロファイルする 間のみ表示されます。プロファイラーで再生モードをターゲットにする 場合、EditorLoop のサンプルは、プレイヤーを含むエディターのレンダリングと実行にどのくらいの時間が費やされたかを示します。 詳細は、再生モードと編集モードのサンプル を参照してください。 |
|
Profiler.CollectEditorStats (エディター専用マーカー) |
各種のアクティブな Profiler モジュールの統計収集に関連するサンプルが含まれます。Profiler.CollectGlobalStats マーカーの下にネストされたサンプルは、プレイヤーが特定のモジュールの統計を収集するときのオーバーヘッドの量を示します。他のすべての子サンプルは、エディターでの影響のみを反映します。特定のモジュールのオーバーヘッドを削除するには、モジュールのチャートを閉じるか、 Profiler.SetAreaEnabled を呼び出します。注意ビルトインカウンターを使用する カスタム Profiler モジュール は、(ビルトインカウンターが属するモジュールが無効になっていても) ビルトインカウンターの領域を有効にします。プロファイラーがこれらの統計を収集して収集オーバーヘッドを発生させないようにするには、ビルトイン Profiler モジュールとカスタム Profiler モジュールの両方が無効になっていることを確認してください。 |
ジョブシステム を使用しない限り、ほとんどのスクリプトコードは以下のマーカーの下にネストされます。ジョブシステムのサンプルについては、マルチスレッドマーカー のセクションを参照してください。
Unity の更新ループの詳細は、イベント関数の実行順序 に関するドキュメントを参照してください。PlayerLoop.SetPlayerLoop を使用して、PlayerLoop に独自のコールバックを挿入できます。メインループに直接コールバックを挿入すると、スクリプトの更新サンプルが単独で表示されます。コールバックをサブシステムとして挿入すると、サンプルはそれぞれメインの PlayerLoopSystem マーカーの下に表示されます。
| マーカー | 説明 |
|---|---|
| BehaviourUpdate |
MonoBehaviour.Update メソッドのすべてのサンプルが含まれます。 |
| CoroutinesDelayedCalls | 最初の yield の後の コルーチン のすべてのサンプルが含まれます。 |
| FixedBehaviourUpdate |
Monobehaviour.FixedUpdate メソッドのすべてのサンプルが含まれます。 |
| PreLateUpdate.ScriptRunBehaviourLateUpdate |
Monobehaviour.LateUpdate メソッドのすべてのサンプルが含まれます。 |
| Update.ScriptRunBehaviourUpdate |
MonoBehaviour.Update と コルーチン のすべてのサンプルが含まれます。 |
これらのマーカーには、CPU が GPU のデータ処理に時間を費やしている箇所、または、GPU の終了を待機しているかもしれない箇所のサンプルが含まれます。GPU Profiler モジュール が使用できない場合やオーバーヘッドが大きすぎる場合は、Profiler モジュールの詳細ペインのツールバーにこの情報は表示されません。これらのマーカーに含まれるサンプルは、アプリケーションが CPU 依存か GPU 依存かを判断するのに役立ちます。
| マーカー | 説明 |
|---|---|
| WaitForTargetFPS |
Application.targetFrameRate が指定するターゲット FPS の待機にアプリケーションが費やした時間を示します。サンプルが Gfx.WaitForPresentOnGfxThread のサブサンプルである場合、アプリケーションが GPU の待機に費やした時間を表します。例えば、QualitySettings.vSyncCount で次の VSync が設定されている場合やターゲットプラットフォームで vSync が適用されている場合に、GPU が次の VSync の待機に要した時間などです。ただし、GPU がフレームの計算を完了していない場合でもこのマーカーを持つサンプルが出力されます。 このマーカーのサンプルが多くの時間を使用する原因を特定するには、CPU Profiler モジュールの Timeline ビュー に切り替えます。このビューでは、レンダースレッドで何が起きたか、現在のフレームで終了するこのサンプルと周囲のフレームで終了する同じサンプルとの間に経過した時間を確認できます。 継続時間がアプリケーションの目標とするフレーム時間 (ターゲットフレームレートまたは vSync に基づく) よりも長い場合、フレームの描画や計算に時間がかかり過ぎています。その場合は、レンダースレッドを調査し、GPU へのコマンドの準備と発行のために行った他の作業と比較して、Gfx.PresentFrame にどのくらい作業時間を費やしているかを確認します。レンダースレッドが Gfx.PresentFrame により多くの時間を費やしている場合、レンダリング作業は GPU 依存です。レンダースレッドがコマンドの準備により多くの時間を費やしている場合、アプリケーションは CPU 依存です。 アプリケーションが GPU 依存の場合に何に重点を置くべきかを判断するには、Unity プロファイラーまたはプラットフォームプロファイラーで GPU 作業をプロファイルします。詳細は、グラフィックスパフォーマンスの最適化 方法に関するユーザーマニュアルドキュメントを参照してください。 注意エディターは GPU で VSync を実行せず、代わりに WaitForTargetFPS を使用して VSync の遅延をシミュレートします。一部のプラットフォーム、特に Android と iOS では VSync が適用されているか、デフォルトのフレームレートの上限が 30 または 60 です。 |
| Gfx.PresentFrame | GPU によるフレームの描画と表示をアプリケーションが待機した時間を示します (VSync の待機も含む)。 メインスレッドの WaitForTargetFPS マーカーのサンプルは、VSync の待機に費やされた時間を示します。 |
| Gfx.ProcessCommands | レンダースレッドのレンダリングコマンドのすべての処理が含まれます。この処理時間の一部は、メインスレッドからの VSync または新しいコマンドの待機に費やされた可能性があります。これは、その子サンプル Gfx.WaitForPresentOnGfxThread から確認できます。 |
| Gfx.WaitForCommands | 新しいコマンドに対し、レンダースレッドの準備ができていることを示します。このマーカーは、メインスレッドのボトルネックを示す場合もあります。 |
<GraphicsAPIName>.WaitForLastPresent 例: GfxDeviceD3D11.WaitForLastPresent GfxDeviceD3D12.WaitForLastPresent GfxDeviceMetal.WaitForLastPresent |
このマーカーのサンプルは、GPU がそのフレーム番号を画面に表示するのをメインスレッドが待機した場合に表示されます (Time.frameCount - QualitySettings.maxQueuedFrames + 1)。つまり、QualitySettings.maxQueuedFrames が 1 より大きい場合、この時間は、アプリケーションがメインスレッドの前のフレームで描画するように要求したフレームを GPU が表示するのを待機するのに費やされる時間を示します。このサンプルの詳細と Unity のフレームパイプラインの概要については、デルタタイムの修正に関する Unity のブログ記事 を参照してください。 |
| Gfx.WaitForPresentOnGfxThread | メインスレッドが次のフレームを描画する準備ができたが、レンダースレッドが GPU によるフレームの表示の待機を完了しなかったことを示します。これは、アプリケーションが GPU 依存であることを示している可能性があります。レンダースレッドが何に同時に時間を費やしているかを確認するには、CPU Profiler モジュールの Timeline ビュー を確認します。 レンダースレッドが Camera.Render で時間を費やしている場合、アプリケーションは CPU 依存であり、GPU へのドローコールやテクスチャの送信に時間をかけすぎている可能性があります。 レンダースレッドが Gfx.PresentFrame で時間を費やしている場合、アプリケーションは GPU 依存であるか、GPU の VSync を待機している可能性があります。Gfx.WaitForPresentOnGfxThread の WaitForTargetFPS サブサンプルは、アプリケーションが VSync の待機に費やした Present フェーズの部分を表します。Present フェーズは、Unity がバッファのスワップをグラフィックス API に指示してから、その操作が完了するまでの時間の部分です。 |
| Gfx.WaitForRenderThread | レンダースレッドがコマンドストリームにあるすべてのコマンドを処理するのをメインスレッドが待機していたことを示します。このマーカーのサンプルは、マルチスレッドレンダリングでのみ表示されます。 |
このサンプルは、Mono または IL2CPP のスクリプティングバックエンドアクティビティを強調しており、ガベージコレクションや割り当てに関する問題のトラブルシューティングに役立ちます。
| マーカー | 説明 |
|---|---|
| GC.Alloc | 自動ガベージコレクションの対象となるマネージ割り当てを含むマネージヒープ内の割り当てを表します。アプリケーションが自動ガベージコレクションに費やす時間を短縮するには、これらのタイプのサンプルを最小化する必要があります。 |
| GC.Collect | ガベージコレクションに関連するサンプルを示します。Unity がガベージコレクションを行う必要があるときは常に、プログラムコードの実行を停止し、ガベージコレクターがすべての作業を終了したときにのみ、通常の実行を再開します。注意インクリメンタルガベージコレクション を有効にした場合、ガベージコレクターは 1 フレームで作業を完了しない可能性があります。 この中断により、アプリケーションの実行に遅延が発生し、1 ミリ秒未満から数百ミリ秒に及ぶ場合があります。これは、ガベージコレクターの処理に必要なメモリの量や、アプリケーションが実行されるプラットフォームによって異なります。詳細は、自動メモリ管理 に関するドキュメントを参照してください。 |
|
Mono.JIT Mono-only |
スクリプトメソッドの実行時コンパイルに関連するサンプルが含まれます。関数が初めて実行されると、Mono はその関数をコンパイルします。Mono.JIT はこのコンパイルのオーバーヘッドを示します。 |
| UnsafeUtility.Malloc | UnsafeUtility.Malloc を呼び出し、アンマネージメモリを割り当てるサンプルが含まれます。ガベージコレクターはこのメモリを追跡しませんが、メモリの割り当てはパフォーマンスに大きな影響を与える可能性があり、このサンプルでそれが示されています。この呼び出しのソースを調べるには、Profiler ウィンドウで、このマーカーの コールスタック の記録を有効にします。 |
これらのマーカーには、消費された CPU サイクルを測定するのではなく、スレッドの同期やジョブシステムに関連する情報を強調するサンプルが含まれます。これらのサンプルが表示された場合、CPU Profiler モジュールの Timeline ビュー を使って、他のスレッドで同時に発生していることを確認してください。
| マーカー | 説明 |
|---|---|
| Idle | ワーカースレッドが非アクティブになっている時間の長さを示すサンプルが含まれます。ワーカースレッドは、ジョブシステムによって使用されないときは常に非アクティブです。待機モードになり、セマフォで待機します。 Idle サンプル間の小さなギャップは通常、例えば新しいジョブをスケジュールするために、ジョブシステムがそれらを起動するときに発生します。長いギャップは、インストルメント化されていないネイティブジョブがスレッド上で実行されていることを示している場合があります。 |
| JobHandle.Complete | ジョブの同期ポイントが発生したときのサンプルが含まれます。同期ポイントが発生すると、アプリケーションのパフォーマンスに影響を与えたり、マルチスレッドのジョブコードの実行に支障をきたしたりする場合があります。同期ポイントが発生した場所を正確に探しやすくするには、このサンプルの コールスタック の記録を有効にします。CPU Profiler モジュールの Timeline ビューで Flow Events を有効にすると、現時点でどのジョブが終了したかを確認できます。 |
| Semaphore.WaitForSignal | スレッドの同期ポイントを示すサンプルが含まれます。待機しているスレッドを見つけるには、Timeline ビューでこのサンプルの直前に終了したサンプルを確認してください。 |
| WaitForJobGroupID | JobHandle に Sync Fence がトリガーされました。作業を完了したワーカーが他のワーカーのジョブを確認して完了する 作業の横取り が発生する可能性があります。その場合は、このマーカーの下に実行されたジョブのサンプルとして表示されます。横取りされたジョブは必ずしも待機されていたジョブとは限りません。 |
以下の表は、高レベルの物理演算プロファイラーマーカーの一部をまとめたものです。 FixedUpdate は、これらの計測をすべて呼び出します。
| マーカー | 説明 | |
|---|---|---|
| Physics.FetchResults | 物理エンジンから物理シミュレーションの結果を収集するサンプルが含まれます。接触ストリーム、トリガーのオーバーラップ、ジョイントの破損イベントなど。 | |
| Physics.Interpolation |
Physics.Interpolation メソッドの実行時間を計測するサンプルが含まれます。このメソッドは、アプリケーションのすべての物理オブジェクトの位置と回転の補間を管理します。 |
|
| Physics.Processing | すべてのスレッドで物理シミュレーションが完了するまで、メインスレッドで待機して時間を費やしたサンプルが含まれます。アプリケーションが Physics.Processing に多くの時間を費やしているにも関わらず、シーンに物理演算に関連するゲームオブジェクトが数個しかない場合、ワーカースレッドがジョブを横取りして他のシステムのタスクを拾い、物理演算として報告した可能性があります。これは、待機中にメインスレッドが優先度の高いキューからジョブを拾うためです。 |
|
| Physics.ProcessingCloth |
Physics.ProcessingCloth メソッドの実行時間を計測するサンプルが含まれます。このメソッドは、すべてのクロスの物理ジョブを処理します。このサンプルを展開すると、 物理演算エンジンで内部的に行われた作業の低レベルの詳細が表示されます。 |
|
| Physics.ProcessReports |
OnTriggerEnter などのコールバックを介して物理演算データをスクリプトに転送するのに要した時間に対応するサンプルが含まれます。注:これらのサンプルは、FetchResults 中にすでに準備されているため、必要なデータを計算しません。4 つの異なるステージがあります。 |
|
| Physics.Contacts |
Physics.Contacts の実行時間を計測するサンプルが含まれます。OnCollisionEnter、OnCollisionExit、OnCollisionStay イベントを処理します。 |
|
| Physics.JointBreaks |
Physics.JointBreaks の実行時間を計測するサンプルが含まれます。壊れたジョイントに関連する更新やメッセージを処理します。 |
|
| Physics.TriggerEnterExits |
Physics.TriggerEnterExits の実行時間を計測するサンプルが含まれます。OnTriggerEnter、OnTriggerExit イベントを処理します。 |
|
| Physics.TriggerStays |
Physics.TriggerStays の実行時間を計測するサンプルが含まれます。OnTriggerStay イベントを処理します。 |
|
| Physics.Simulate |
Physics.Simulate メソッドの必要条件の作業時間を計測するサンプルが含まれます。このメソッドは物理演算エンジンにシミュレーションの実行を指示し、現在の物理演算の状態を更新します。 |
|
| Physics.UpdateBodies | すべての物理演算ボディの位置と回転を更新するサンプルが含まれます。このマーカーを持つサンプルは、Rigidbody コンポーネントを持つ各ゲームオブジェクトに対して、物理演算エンジンからポーズを読み取り Transform に書き込みます。 | |
| Physics.UpdateCloth |
Physics.UpdateCloth メソッドの実行時間を計測するサンプルが含まれます。このメソッドは、クロスとそのスキンメッシュに関連する更新を処理します。 |
|
スクリプトのライフサイクルと、スクリプトのライフサイクル内の一般的なサンプルについては、イベント関数の実行順序 のドキュメントを参照してください。
以下の表に、アニメーションシステム のマーカーを示します。アニメーションシステムのパフォーマンスに関する一般的な情報は、Mecanim のパフォーマンスと最適化 のページを参照してください。
このステージでは、アクティブで有効なすべてのアニメーターが処理されます。アクティブなアニメーターは、Culling Mode や可視性に関係なく処理されます。
Director. で開始するマーカーは、Playables と Timeline もカバーできます。
| マーカー | 説明 |
|---|---|
| Director.PrepareFrame |
Director.PrepareFrameJob ジョブの設定、スケジュール設定、待機を行います。これらのジョブは、すべてのアクティブなアニメーターコンポーネントのステートマシンを評価します。 |
| Director.PrepareFrameJob (job) | 1 つのアクティブなアニメーターのステートマシンを評価します。アニメーターの処理にかかる時間は、ステートマシンの複雑さ (ステート、遷移、プロパティ、レイヤーの数など) に応じて増加します。OnStateMachineEnter、OnStateMachineExit リスナーを実装する StateMachineBehaviours を持つステートマシンの評価は、メインスレッドに制約されます。 |
| Animators.PrepareFirstPass | 次の処理ステップの準備をします。 |
| Animators.ProcessGraphJob |
Animator.ProcessGraph ジョブのビルド、スケジュール設定、結果の待機を行います。 |
| Animators.ProcessGraph (job) | 接続されているすべての AnimationClip のすべてのプロパティを評価します。 すべてのクリップのルートモーションプロパティをブレンドして、ルートモーションのディスプレイスメントを計算します。 現在の deltaTime の新しいアニメーションイベントを収集します。AnimationClip のプロパティを評価するとき、カーブセグメントはフレーム間でローカルにキャッシュされ、AnimationClip のメモリからの必要以上の読み取りを防ぎます。 |
| Animators.FireAnimationEventsAndBehaviours |
StateMachineBehaviours と MonoBehaviour のすべてのアニメーションイベントメッセージを起動します。ただし、Director.PrepareFrameJob ですでに発生している OnStateMachineEnter または OnStateMachineExit リスナーは除きます。 |
| Animators.ApplyOnAnimatorMove | MonoBehaviour にルートモーションを適用し、OnAnimatorMove メッセージをトリガーします。 |
このステージでは、Culling Mode が Always Update のアニメーターと、Culling Mode が UpdateTransform または Cull Completely の表示中のアニメーターだけが処理されます。Cull Completely を持つアニメーターがルートモーションによってフレーム外に移動した場合、このフェーズには参加しません。StateMachineBehaviours と AnimationEvents でトリガーされたユーザーコードによって無効化されたアニメーターも同様です。
| マーカー | 機能 |
|---|---|
| Animators.PrepareSecondPass | 次の処理ステップを設定します。Culling Mode と可視性の状態に基づくアニメーターのフィルタリングが含まれます。 |
| Animators.SortWriteJob | Transform システムでは、一度に 1 つのスレッドだけが Transform 階層を変更できます。この制限に対応するために、Animators.SortWriteJob は Animators.WriteTransforms ジョブを Transform.root でグループ化します。最高のパフォーマンスを得るには、ジョブのスケジュール設定と並列化の粒度を高めるために、同じ Transform 階層に複数の Animator を配置することは避けてください。 |
| Animators.ProcessAnimationsJob |
Animators.ProcessAnimations ジョブのビルド、スケジュール設定、結果の待機を行います。 |
| Animator.ProcessAnimations (job) | 1 つのアニメーターの現在アクティブな AnimationClip のすべてのプロパティをブレンドします (ルートモーションを除く)。アバターの内部表現に適用されます。 このマーカーの長さはアニメーションとブレンドの複雑さに応じて増減します。 |
| OnAnimatorIK | アニメーション IK を設定します。IK パスが有効なアニメーターコントローラーレイヤーごとに 1 回呼び出されます。 |
| Animators.WriteJob |
Animator.WriteTransform ジョブのビルド、スケジュール設定、結果の待機を行います。これらのジョブは、アニメーションアバターから関連するゲームオブジェクトの Transform 階層に Transform のポーズを書き込みます。 |
| Animators.WriteTransforms (job) | ワーカースレッドからシーンにアニメーション化されたすべての Transform を書き込みます。 |
| Animator.WriteProperties | Transform のポーズ以外のアニメーション化されたプロパティをターゲットオブジェクトに書き込みます。 |
CPU Profiler は、いくつかの一般的なパフォーマンス問題を検出し、警告を発します。これらは、モジュールの詳細ペインの CPU Profiler モジュールの Hierarchy ビューの Warning 列に表示されます。
プロファイラーは、パフォーマンスに重要なコンテキストで避けるべき特定の呼び出しを検出します。以下のように、操作がパフォーマンスに影響を与えている理由とともに警告を表示します。
| 警告 | 説明 |
|---|---|
|
Animation.DestroyAnimationClip Animation.AddClip Animation.RemoveClip Animation.Clone Animation.Deactivate |
RebuildInternalState がトリガーされたことを示します。RebuildInternalState は、Animation コンポーネント内の各クリップのリストを参照し、各カーブをゲームオブジェクトのコンポーネント上の値に再バインドする操作です。 これはリソースに負荷がかかる操作であるため、ランタイムにこれらのメソッドを呼び出すことはできるだけ避ける必要があります。 |
| AssetBundle.asset/allAssets | AssetBundle の読み込みが完了していない状態 (AssetBundleRequest.isDone が false) で Unity が AssetBundleRequest.assets/allAssets API を呼び出したことを示します。これにより、メインスレッドでストールが発生し、ロードの操作が完了するのを待機します。 |
|
AsyncUploadManager.AsyncBufferResized AsyncUploadManager.AsyncBufferDelete |
GPU にデータをアップロードするための内部バッファのサイズが十分でないために、サイズ変更されていることを示します。このサイズ変更には時間がかかるため、CPU アクティビティのスパイクの原因になります。 この警告は、メモリに余裕があり事前に大きいサイズを割り当てられる場合は回避できます。 品質設定 の Async Upload Buffer Size 設定を使用して、デフォルトサイズを設定できます。 AsyncUploadManager.AsyncBufferResized マーカーは新しく割り当てられたサイズを示し、デフォルトバッファサイズの目安として使用できます。 |
| Rigidbody.SetKinematic | Rigidbody 用の非凸のメッシュコライダーを再作成します。 |