CPU と GPU のフレーム処理時間を見積もる

CPU と GPU のフレーム処理時間(フレーム時間)を推定することは、アプリのパフォーマンスを把握し、ボトルネックを特定するために不可欠です。AGI でアプリをプロファイリングすると、System Profiler からフレーム時間を推定するために使用できるトレースデータが提供されます。

CPU 時間

AGI では、システム プロファイルの CPU トラックで、CPU フレームの合計時間とアクティブ時間を表示できます。

合計 CPU 時間

消費された合計 CPU 時間を測定するには、連続するフレーム送信イベント間の時間を含める期間を選択します。フレーム送信イベントは、eglSwapBuffers(OpenGL の場合)と vkQueuePresentKHR(Vulkan の場合)です。

eglSwapBuffer イベントのスクリーンショット。
図 1. 2 つの eglSwapBuffer イベント間の時間。


vkQueuePresentKHR イベントのスクリーンショット。
図 2. 2 つの vkQueuePresentKHR イベント間の時間。

この測定値は CPU の合計時間の推定値ですが、アクティブな CPU 時間を表すものではありません。たとえば、GPU バウンド アプリでは、CPU が GPU の処理が完了するのを待ってから新しいフレームを送信する場合があります。これは、dequeueBuffereglSwapBuffer(OpenGL の場合)、vkQueuePresent(Vulkan の場合)イベントが CPU 時間の大部分を占有している場合によく発生します。待機時間は合計 CPU 時間には含まれますが、アクティブな CPU 時間には含まれません。

dequeueBuffer イベントと eglSwapBuffer イベント中に大量のアイドル状態を示すスクリーンショット。
図 3. dequeueBuffer イベントと eglSwapBuffer イベント中に大量の CPU アイドルが発生している。

アクティブな CPU 時間

アクティブな CPU 時間は、CPU がアイドル状態にならない状態でアプリコードを実行している時間を示します。

アクティブな CPU 時間を測定するには、CPU イベントのすぐ上にある [実行中] スライスを確認します。2 つのフレーム送信イベント(実行中状態)間のトレースのすべての部分をカウントします。動作中のスレッドが含まれていることを確認します。

アクティブな CPU 時間を測定するために使用できる 2 つの期間の CPU 時間のスクリーンショット。
図 5. アクティブな CPU 時間を測定するために使用できる 2 つの CPU 時間。


メインスレッドがアイドル状態のときに他のスレッドが処理中であるマルチスレッド アプリのスクリーンショット。
図 6. メインスレッドがアイドル状態のときに他の処理スレッドがあるマルチスレッド アプリ。

アクティブな CPU 時間を測定する別の方法は、CPU トラックでアプリスライスを確認することです。これらのスライスは、CPU が実行されているときを示します。これらは [実行中] スライスに相当します。

CPU トラックと一致する固定スレッドの実行状態を示すスクリーンショット。
図 7. 固定されたスレッドの実行状態が CPU トラックと一致している。

アプリスライスを識別するために、アプリに ATrace マーカーを追加できます。これにより、システム プロファイラの CPU トラックにマーカーが表示されます。

CPU トラックに表示された ATrace スライスのスクリーンショット。
図 8. CPU トラックに表示された ATrace スライス。

GPU フレーム時間を推定する

GPU フレーム時間を推定するには、システム プロファイラで GPU スライスまたは GPU カウンタを使用します。GPU スライスを使用すると、推定値の精度が向上します。

GPU スライス

システム プロファイラに GPU スライス情報が含まれている場合は、1 つのフレームに関連付けられたタスクの処理にアプリが費やした合計時間を測定することで、非常に正確な GPU フレーム時間情報を取得できます。

Mali デバイス

Mali デバイスでは、GPU スライスにはフラグメント非フラグメント、場合によっては補足非フラグメント トラックがあります。複雑でないフレームの場合、フラグメントとフラグメント以外の処理は順番に行われるため、アクティブな GPU 処理間のギャップを確認することで、フレーム間の処理を区別できます。

または、GPU に送信される作業に精通している場合は、送信されたレンダリング パスのパターンを特定することで、フレームの開始と終了に関する情報を取得できます。

複数のフレームが順番に実行されているスクリーンショット。
図 9. 複数のフレームが順番に実行される。
AGI が個々のフレームの作業にズームインしているスクリーンショット。
図 10. 個々のフレームの作業を拡大表示。

GPU ワークフローがより高度に並列化されているアプリの場合は、各スライスの [選択] ペインで同じ submissionID を持つすべてのフレームを探して、GPU フレーム時間を取得できます。

Vulkan ベースのアプリでは、複数の送信を使用してフレームを合成できます。送信 ID を追跡するには、Vulkan Events トラックを使用します。このトラックには、送信ごとにスライスが含まれています。送信スライスを選択すると、送信に対応するすべての GPU アクティビティ スライスがハイライト表示されます。

並列化された GPU ワークロードのスクリーンショット。1 つのフレームの処理が別のフレームの処理と重複する場合があります。
図 11. 1 つのフレームの仕事が別のフレームと重複する可能性がある並列化された GPU ワークロード。


フレーム用に選択された複数の Vulkan イベントのスクリーンショット。
図 12. フレームに対して選択された複数の Vulkan イベント。

Adreno デバイス

Adreno デバイスでは、GPU スライスは [GPU Queue 0] トラックに表示され、常に順番に表示されます。そのため、フレームのレンダリング パスを表すすべてのスライスを確認し、それらを使用して GPU フレーム時間を測定できます。

複数のフレームが順番に実行されているスクリーンショット。
図 13. 複数のフレームが順番に実行される。
複数のレンダリング パスを含むフレームで AGI がズームインされているスクリーンショット。
図 14. 複数のレンダリング パスを含むフレームをズームイン。

前述の Mali のシナリオと同様に、アプリが Vulkan を使用している場合、Vulkan イベント トラックには、フレームの実行のために送信されたワークに関する情報が表示されます。レンダリング パスをハイライト表示するには、フレームに関連付けられている Vulkan イベントスライスをクリックします。

フレームの Vulkan イベントが選択されている Vulkan ベースのアプリのスクリーンショット。
図 15. フレームの Vulkan イベントが選択されている Vulkan ベースのアプリ。

アプリが GPU に大きく依存しているため、GPU フレームの境界を区別するのが難しいシナリオもあります。このようなシナリオでは、GPU に送信される作業に精通している場合は、レンダリング パスが実行されるパターンを特定し、その情報からフレーム境界を決定できます。

フレーム境界を特定するのに役立つレンダリング パス パターンが適用された、GPU に負荷の高いアプリのスクリーンショット。
図 16. フレーム境界を特定するのに役立つレンダリング パス パターンを使用する、GPU に大きく依存するアプリ。

GPU カウンタ

トレースから GPU スライス情報を取得できない場合は、GPU カウンタ トラックを使用して GPU フレーム時間を推定できます。

Mali デバイス

Mali デバイスでは、GPU 使用率トラックを使用して、GPU 使用率が高くないアプリの GPU フレーム時間を推定できます。アプリの GPU 使用率が低い場合、GPU アクティビティは一定ではなく、高くなる期間と低くなる期間が定期的に繰り返されます。GPU 使用率トラックを使用して GPU フレーム時間を推定するには、トラック内のアクティビティが多い期間の長さを測定します。

Mali デバイスの GPU 使用率と GPU キュー トラックのスクリーンショット。
図 17. Mali デバイスの GPU 使用率と GPU キューのトラック。

アプリが GPU をより多く使用している場合、GPU の使用率は常に非常に高くなる可能性があります。この場合、フラグメント キューの使用率フラグメント以外のキューの使用率のトラックを使用して、GPU アクティビティをモニタリングし、GPU フレーム時間を推定できます。フラグメント トラックとフラグメント以外のトラックでパターンを探すことで、フレームの境界を大まかに推定し、それを使用して GPU フレーム時間を測定できます。

フラグメント トラックとフラグメント以外のトラックのスクリーンショット。
図 18. フラグメント トラックとフラグメント以外のトラック。

Adreno デバイス

Adreno デバイスで、アプリが GPU を多用していない場合は、前のセクションの Mali デバイスと同じ方法で GPU フレーム時間を推定できます。

Adreno デバイスの GPU 使用率と GPU キュー トラックのスクリーンショット。
図 19. Adreno デバイスの GPU 使用率と GPU キュー トラック。

アプリが GPU 使用率が高く、アプリケーションの GPU 使用率が常に高い場合は、[Vertex Instructions / Second] トラックと [Fragment Instructions / Second] トラックを使用して GPU フレーム時間を推定できます。これらのトラックのアクティビティ レベルにパターンを探すことで、フレームの境界を大まかに推定し、それを GPU フレーム時間を測定するために使用できます。

Vertex の手順 / 2 番目のトラックのスクリーンショット。
図 20. [Vertex Instructions / Second] トラック。

次のような他のトラックでも同様の情報が提供される場合があります。

  • シェーディングされた頂点数 / 秒
  • シェーディングされたフラグメント / 秒
  • % Time Shading Vertices(シェーディング頂点の時間の割合)
  • % Time Shading Fragments