about:トレースを使用したWebGLゲームパフォーマンス分析

測定できないものも改善されません。

-ケルビンLord


HTML5を使用して記述されたゲームを高速化するには、まずボトルネックを特定する必要があります。 FPSのカウントは良い方法ですが、詳細をすべて表示するには、Chromeの動作の微妙な違いを理解する必要があります。



about:トレースツールは、パフォーマンスの向上に関連する不必要な作業を回避し、主に推測に基づいています。 このツールを使用してブラウザを明確にトレースすると、エネルギーとお金を節約できます。



これは、Chromeが実行するすべてを示し、最初は気絶するほど詳細に表示します。 Chromeの機能の多くは主にトレース用に設計されているため、次のように使用できます。ボックスから直接トレースしてパフォーマンスを評価します。



これを行うには、アドレスバーでトレースするだけです。



画像



トレースツールを使用すると、記録を有効にし、数秒間ゲームを開始し、トレースデータを確認できます。 どのように見えるかの例:



画像



はい、最初はわかりにくいようです。



各行は、追跡しているプロセスです。 左から右への軸は時間を示し、色付きの長方形は関数呼び出しを示します。 このシリーズはさまざまなリソース向けに提示されていますが、GPUとCrRendererMainの動作を示すCrGpuMainに最も関心を持っています。 各トレースには、開いているタブごとにCrRendererMain行があります(about:トレースタブ自体を含む)。



最初のタスクは、ゲームに対応するCrRendererMainシリーズを決定することです。



画像



この例では、2216と6516の2つの候補があります。残念なことに、定期的に更新する行を検索する以外に、アプリケーションを選択する簡単な方法はありません(または、追跡ポイントを使用してコードを調べる場合、追跡データを含む行) この例では、6516が多くの更新を実行することがわかります。 余分なタブをすべて閉じると、検索プロセスが簡単になります。 しかし、それでも、他のプロセスのCrRendererMainシリーズがここに到達できます。



フレームを探しています



目的の行が見つかったら、メインサイクルの検索を開始する必要があります。 繰り返しパターンのように見えます。 WASDを使用して追跡データに沿って歩くことができます-AボタンとDボタンを使用すると、左右に(時間的に前後に)移動でき、WとS-画像を増減できます。 ゲームを60 Hzで実行する場合、メインループは16ミリ秒ごとに繰り返す必要があります。



画像



「ハートビート」を見つけたら、コードの詳細な調査を開始できます。 W、A、S、Dを使用して、テキストが表示されるまで画像を拡大します。



画像



長方形は関数呼び出しのシーケンスを示し、それぞれが独自の色付きの長方形で表されます。 各関数は上の長方形から呼び出されたため、この場合、MessageLoop :: RunTaskがRenderWidget :: OnSwapBuffersCompleteを呼び出し、RenderWidget :: DoDeferredUpdateなどを呼び出したことが明らかです。 そのため、何が起こっているのかを完全に把握できます。



確かに、この情報はChromeソースコードからの生の呼び出しです。 もちろん、各関数が何をするかは推測できますが、情報は特に便利ではありません。 もっと人間が読めるものが必要です。



追跡タグを追加する



そして、そのような可能性が存在します-それはconsole.timeとconsole.timeEndです。



console.time("update"); update(); console.timeEnd("update"); console.time("render"); update(); console.timeEnd("render");
      
      







このコードは、指定された名前で新しい長方形を作成するため、レポートに「update」と「render」が表示され、これらのラベルの呼び出しの間に経過した時間が表示されます。



画像



GPUまたはCPU?



グラフィックアクセラレータを使用している場合、プロファイリングの主な問題の1つは、コード、GPU、またはCPUに過負荷をかけることです。 各フレームは、一方と他方の両方からリソースを取得します。 ブレーキがどこに隠れているかを理解するには、それらの仕事のバランスを見る必要があります。



GPUがビジーであることを示すCrGPUMainという名前の行を見つけます。



画像



各フレームで、CrRendererMainのCPUとGPUの両方が機能することがわかります。 この図は、ほとんどの場合、両方のプロセッサがアイドル状態になっている非常に単純なケースを示しています。



このスケジュールは、ゲームが本当に遅くなり始め、どのリソースが不足しているかわからない場合に役立ちます。 前の例を使用して、更新ループの負荷を追加します。



 console.time("update"); doExtraWork(); update(Math.min(50, now - time)); console.timeEnd("update"); console.time("render"); render(); console.timeEnd("render");
      
      







トレースは次のようになります。



画像



これはどういう意味ですか? フレームは、2270msの瞬間から2320msの瞬間まで時間がかかります。つまり、それぞれが50ミリ秒(周波数20 Hz)でレンダリングされます。 細長いストライプは、更新長方形の横にあるレンダリング関数を表しますが、ほとんどの場合、更新関数は常にビジーです。



GPUはほとんど常に静止していることがわかります。 コードを最適化するには、シェーダーを介して実行できる操作を探し、GPUに送信する必要があります。



しかし、シェーダーコードの速度が低下し、GPUが過負荷になった場合はどうでしょうか。 CPUの不要な作業を削除して、シェーダーに作業を追加しましょう。 役に立たないシェーダーダウンロードの例を次に示します。



 #ifdef GL_ES precision highp float; #endif void main(void) { for(int i=0; i<9999; i++) { gl_FragColor = vec4(1.0, 0, 0, 1.0); } }
      
      







その場合、コードトレースはどのようになりますか?



画像



フレームの持続時間に注意してください。 2750ミリ秒から2950ミリ秒、つまり200ミリ秒(5 Hz) CrRendererMain行はほとんど空です。つまり、CPUは休止しており、GPUが過負荷になっています。 これは、オーバーロードされたシェーダーの明確な兆候です。



人生の例



実際のゲームの追跡データがどのように見えるかを確認しましょう。 オープンソース技術の素晴らしいところの1つは、お気に入りの製品を掘り下げられることです。 Chrome Web StoreからWebGLの任意のゲームを取得し、トレース:についてプロファイルできます。 スキッドレーサーゲームのトレースの例を次に示します。



画像



どうやら、各フレームは20ミリ秒間レンダリングされます。つまり、周波数は約50 Hzです。 CPUとGPUの間で作業がどのようにバランスが取れているかを確認できますが、GPUの方が機能します。 実際の例を使用して、Chromeウェブストアから次の製品を追跡してみてください。







おわりに



ゲームを60 Hz FPSで動作させる場合、各フレームはCPUとGPUの両方の時間で16ミリ秒以内に作成する必要があります。 これらの2つのリソースは並行して使用でき、生産性を最大化するために、作業をそれらの間で分割できます。



次は?



GPUに加えて、他のChromeコンポーネントを追跡できます。 現在のChromeトレース機能の理解を深めるには、Chromiumに関する記事を読んでください。



WebGLゲーム開発者は、次のビデオを視聴することをお勧めします-これは、GoogleのGame Developer AdvocateチームとGDC 2012によるChromeのゲームパフォーマンスの最適化に関するプレゼンテーションです。






All Articles