ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
Apple GPU向けのハイエンドゲームの最適化
Apple GPU向けのハイエンドゲームの最適化: Appleのレンダリングツールやデバッグツールを使用して、パフォーマンスの問題を解決し、Appleプラットフォームで素晴らしいゲームを作る方法を紹介します。Larian Studiosや4A Gamesの開発者と協力して、Apple GPU向けにゲームを最適化した経験についてお伝えします。 シェーダの最適化、メモリ帯域幅の使用量の削減、GPUワークロードのオーバーラップの増加など、ゲームのパフォーマンスを向上させるためのさまざまなテクニックを検証します。また、Xcode 13に搭載された新しいGPUタイムラインプロファイリングツールを使って、”Divinity: Original Sin 2”をiPadで動作させた場合に考えられるパフォーマンスのボトルネックを特定します。 このセッションのためには、Apple GPUのタイルベースの遅延レンダリングアーキテクチャを理解している必要があると共に、XcodeとMetal APIに関する実用的な知識が必要です。 「Metalのデバッグ、プロファイリング、アセット作成ツール」またはWWDC20のセッション「GPUカウンタによるMetalのAppやゲームの最適化」をご確認いただき、Appleのツールを使用してグラフィックスワークロードをプロファイリングする方法の詳細をご確認ください。
リソース
- Debugging the shaders within a draw command or compute dispatch
- Metal
- Metal Performance Shaders
- Metal Shading Language Specification
関連ビデオ
WWDC21
- Metalでのバインドレスレンダリングの詳細
- Metalのデバッグ、プロファイリング、アセット作成ツール
- Metalレイトレーシングによるハイブリッドレンダリング
- MetalレイトレーシングによるAppの強化
WWDC20
-
ダウンロード
WWDCへようこそ Jonathan Metzgarです Metal Ecosystemチームの メンバーです 私たちはゲームデベロッパが 最高のグラフィック パフォーマンスを達成する お手伝いをしています Dustinと一緒に 高性能のゲームを Apple GPU向けに最適化する 方法を紹介します このビデオでは ゲームの最適化の プロセスについて説明します また 「バルダーズ・ゲート3」と 「メトロ エクソダス」に使用された 最適化の方法についても説明します そして最後に Dustinがツールの実践を 「Divinity: Original Sin 2」 で行います Xcode 13の新しい GPU Timelineを紹介します ではさっそく最適化について お話ししましょう 過去1年間 私たちは Larian Studiosおよび 4A Gamesとグラフィック パフォーマンスをApple GPUに 調整することに取り組みました 詳細を提供できることに ワクワクしています またこのプレゼンのために 開発中のゲームを公開してくれた この2社に感謝します 過去1年間を振り返ると 私たちは多くのゲームを分析し グラフィックに影響を与える 一般的なシナリオを 特定してきました 皆さんはおそらく ご自身の ゲームを最適化する― 機会をお探しでしょう そこでこのセッションでは 当社のGPUツールが問題を 特定するのにいかに役立つか そしてそれらの問題の解決方法を 提案することに焦点を置きます 特に デベロッパによる 最適化を支援する際に 私たちのチームが使用する 原則を紹介します グラフィックなAppの最適化には 特定の問題の解決方法を定義する 方法論や一連の原則が 重要となります では4つのステップの プロセスをご紹介しましょう まず ゲームで起こっている 問題を把握するために どのデータを収集 または測定するかを 選択する必要があります データの測定の開始直後に パフォーマンス目標を決定し 測定終了後に望む 結果を選択します インゲームのロケーションを決定し GPUフレームキャプチャや Metal System Trace シーンの複雑性 グラフィックの設定 フレーム時間など その他の 重要な測定を行います そしてデータを分析し エンジンの状態を把握します 詳細な分析は ボトルネックが発生する 場所と理由を発見するのに役立ちます ボトルネックの原因を把握したら ゲームを改善できますが 1つか2つずつ変更し 各変更の影響を理解します 最後に当初の測定と新しい測定を比較し 改善を確認します 最適化はプロセスなので パフォーマンス目標を 達成するまで この作業を繰り返します これらのゲームにはXcodeの Metal Debuggerを使用し パフォーマンスについての洞察を得て フレームグラフの構造を 把握しました また Instrumentsの Metal System Traceで ゲームの経時的な パフォーマンスを捉えました GPUトレースファイルと Instrumentsの トレースファイルを保存し 最適化前と後の 両方のデータを取得します 皆さんがご自身のゲームで 考慮する事項や 探すべき事項が いくつかあります 前述の通り Xcodeと Instrumentsは MetalのAppの理解に役立つツールです 最適化とはシェーダ パフォーマンスから メモリ帯域幅などの分野を 活用するためのものです もう1つの部分は 頂点 フラグメント ワークロードの計算を オーバーラップさせることで 一部のApple GPUは いくつかのフレームを レンダリングの間に オーバーラップすることがあります オーバーラップを妨ぐ リソースの依存関係について 役立つヒントを説明しましょう またシェーダにカスタム ワークフローを使用する デベロッパもいるので コンパイラ設定による パフォーマンスの影響に ついてもお見せします さらに冗長な バインディングを削減する 方法についてもお話しします ではLarian Studiosの 「バルダーズ・ゲート3」について このゲームは 20年にわたる 伝説的なゲームをもとに 構築されたRPGで 映画のような視覚効果が特徴的です Larian Studiosとの提携により 同社のすばらしい レンダリングエンジンを Apple GPU向けに最適化する 方法を特定できました まず GPUフレーム キャプチャから始めました この荒れた 海岸のシーンなどがそうです 次に シーンをフレーム グラフに分解しました フレームグラフは 各レンダリングパスの 順序と目的を 分解したものです 高性能なゲームには アンビエントオクルージョン シャドウマッピング ポストプロセスなど 特定の視覚効果に特化した レンダリングパスがあります 「バルダーズ・ゲート3」は フレームグラフが複雑です これは簡素化されたバージョンです XcodeのMetal Debuggerで GPUトレースを捉え ゲームのレンダリングパスを 確認するのに使用しました を クリックすると― パンと拡大が可能な 視覚化を表示できます レンダーパスが過去の結果に いかに依存するかが表示され 何が起こっているかを 把握するのに役立ちます たとえば 今私は 詳細を得るために― 据え置きのデカールレンダー ステージを拡大しています 次は Instrumentsの ツールを紹介します Metal System Traceまたは Game Performanceテンプレートで Instrumentsトレースを使い ゲームを分析しました Metal System Traceは GPUの実行と分析の予約に 集中したい場合に最適で Game Performanceは スレッドストールや サーマル通知など その他の問題にも役立ちます ではMetal System Traceを選択して フレームごとにエンジンの 状態を見てみましょう Instrumentsは タイムラインに沿って― 一部のチャネルのデータを 確認するのを可能にします ここで最初の問題が 見つかりました レンダーパスにある 高価なワークロードです これはシェーダを 最適化する必要がある 可能性を指しています たとえば長いCompute Shaderが― 残りのフレームを停滞させて いるのが確認できます このギャップが“バブル”と 呼ばれるものです GPUトレースに戻り― これをさらに調査してみましょう これはGPUトレースの前です グループをAPIコールから パイプライン状態に変えます パイプライン状態が― 実行時間により ソートされています 最初の計算パイプラインを 確認しましょう 計算関数の詳細を拡大して― 統計をさらに詳しく 見ることができます 4,500件以上の― 命令があります かなり多いですね 他はどうでしょうか この計算関数には どんなリソースが― 使用されているでしょうか 入力されたデータにより この機能は― 出力を生成するために120の テクスチャを使用しています しかし実際の使用は 90%の割合で 6~12の テクスチャだけでした ではシェーダを改善する 方法についてお話しします さまざまな条件を処理する 必要のあるシェーダは― 必要以上にレジスタを 蓄積することになり― 並行して実行するスレッドを 削減してしまいます ワークロードを レジスタを多く必要としない 小さくてより集中した シェーダに分けることで― シェーダコアの活用が 改善されます シェーダの適切な アルゴリズムを選択する 代わりに 適切なシェーダ 配列を選択して― GPUワークロードを発行します さらにシェーダ関数が レジスタを選択しすぎると― レジスタプレッシャーにつながり 実行ユニットがレジスタメモリ不足 となり デバイスメモリに切り替わります 16ビットタイプを使用するのは― そのためです 32ビットタイプの― 半分しか場所を取らないからです この場合 Larian Studiosは すでにシェーダを最適化し 半精度浮動小数点を使用して 代わりに専用の シェーダバリアントを 使用することにしました その結果を見てみましょう 前回の左のボックスの数値を― 右のボックスの数値と比較すると― 命令は84% ブランチは90%削減され レジスタは25% テクスチャリードは92%削減 このシェーダバリアントは 90%の割合で使用されました これは Metal System Traceでも確認できます 先ほど確認したトレース前の― バブルに注目してください トレース後に最小化されています Larian Studiosはこのシェーダを― 平均8ミリ秒で削減できました 大成功です 最も高価なパイプライン 状態オブジェクトと― シェーダに目を向けると 複雑なシェーダを― 簡素化できる場合が あるのに気づきます これはそのシェーダの結果が 後のパスで― 使用される場合に その傾向が強くなります これはゲームを 大きく改善しましたが― デベロッパの目標は 達成できませんでした メモリに問題があると 述べましたが― 当社のGPUの特徴の1つは 可逆圧縮で― これは特定の状況で 有効化されます ですのでフラグが 誤って付けられたか― 付けるのを 忘れた場合があります 可逆圧縮は テクスチャが タイルからデバイスメモリに 保管された時に圧縮し 帯域幅を削減します サマリーページの 帯域幅の洞察を見ると― いくつかのテクスチャへの― 可逆圧縮の警告を 確認できます これらのテクスチャは― 可逆圧縮できないことを 知らせており― 帯域幅に対する罰金を 支払うことになりかねません Metal Debuggerも これらのテクスチャが― 可逆圧縮できない理由を 教えてくれます ここでは ShaderWriteの 使用フラグが原因です メモリセクションですべての 使用フラグを確認できます レンダー目標別に フィルタリングができます 次にテーブルヘッダーを 右クリックして― テクスチャを選び 使用法を選びます それでは使用法でソートし― ShaderWriteを使用して テクスチャを探します テクスチャを作成する時に ShaderWriteか― PixelFormatViewフラグを 使用した場合 可逆圧縮が無効になります これらのフラグを より詳しく見てみましょう 未知のShaderWriteと PixelFormatViewフラグは― テクスチャの可逆圧縮を 防止します 一般的にこれらのフラグは 必須の場合のみ― 使用します たとえばwrite()メソッドで フラグメントや― 計算機能からテクスチャに 値を保管する場合に ShareWriteフラグを 使用します テクスチャにレンダリングし カラーアタッチメントに― バインドする場合 ShaderWriteフラグは不要で コンポーネント値を 異なる順番で読み込む― 必要があるだけの場合は PixelFormatViewを 設定しないでください 代わりに Swizzleパターンを使用して テクスチャビューを作成し 新しい順序を指定します テクスチャビューの変換が 線形空間とsRGB間のみの場合 PixelFormatView オプションは設定しません 詳細については 付随資料をご覧ください シェーダの最適化と 可逆圧縮の― 2つの技術は 役に立ちましたが― もう1つの問題は 頂点 フラグメント 計算チャネルの オーバーラップです チャネル全体の ワークロードを最適化する― 2つの方法を見てみましょう まずここでも Metal System Traceに目を向けます ここでの頂点 フラグメント 計算チャネルの― オーバーラップが 低いことがわかります これを改善し GPUを忙しい 状態に保ちたいところです この問題を解決する1つの 方法は フレームグラフで― エンコードの順序の再構築が できるか確認することです 言い換えれば この作業を 占有率が非常に低い― 頂点のステージに 移動させるということです これらの頂点を レンダーパスの― フラグメントステージと共に 早期に処理します フレームグラフを この擬似コードの例のように レンダリングタスクの リストとして考えます 良好なオーバーラップは 単にフレームグラフの― レンダータスクの順序を 変えるだけで達成できます 早期の結果に依存する タスクもありますが― 必ずしもそうではありません CascadedShadowBuffer ステージは― 頂点シェーダを中心にし 依存関係が少ないため― 早期のタスクに 移動することができます これにより オーバーラップが低い― 頂点とフラグメント チャネルの活用が― 改善され1ミリ秒 短縮されています しかし他にも― 最適化の方法があります ゲームはしばしば 処理中に 2~3のフレームがあります 当社のタイルベースの 遅延レンダリング TBDRアーキテクチャGPUは― 2つのフレーム間にリソース 依存関係がない場合に オーバーラップさせる すばらしい機能です この可能性を 最適化する方法を― お見せしましょう 再び InstrumentsでGPU トラックを見てみましょう ここでは これらのフレームは― ほぼ連続的に 処理されています これは転送エンコーダで アニメーションデータなどの 定数バッファを更新しているのが原因です 定数バッファデータを 個別のGPUで更新するには CPUの共有バッファからGPUの プライベートバッファに 転送し フレームの レンダリングに使用します この戦略は離散メモリの GPUに効率的なので― その目的には この動作を保ちましょう 統合メモリアーキテクチャが デバイスに装備されている場合 転送エンコーダを使用して データを複製する必要はありませんが リングバッファパターンで 共有バッファを使用する場合 同期の問題に気をつけてください CPUが現在GPUにより 読み込まれているデータに 書き込む際に 視覚的破損が 生じる場合があるからです これを実際に見てみましょう この図では フレームの― エンコーディングと レンダリングが確認できます 色を使用し 共有バッファを― 表しており フレームの始めに― 更新されています 青色はバッファ1 緑色はバッファ2 黄色はバッファ3です リングバッファは通常 キューの実装に使用され― それには圧縮された メモリが必要となります この配列では 共有バッファの― 書き込みと読み込みが 相互排他的なため― データ競合状態の 心配はありません フレームのエンコーディングと レンダリングの間のレイテンシは 一般的です これによりレンダリングが― 実際に開始される時間が 変化します レイテンシが長すぎない限り― データ競合状態は 起こりません しかしレイテンシの増加が 継続する場合は? そうなるとメインスレッドは GPUがフレームを― レンダリングする間に 共有バッファを更新し― データ競合状態に つながります そしてフレームの要素が このデータに依存する場合 視覚的破損が起こります 「バルダーズ」の場合 プライベートバッファと― 転送エンコーダの削除で 同期点が消去されましたが― 競合状態を取り入れたため 時間的アンチエイリアスの レンダーパスに 影響を及ぼしました この状態を避ける方法を 見てみましょう 競合状態を避けるには― GPUが読み込んでいる 同じリソースに― 書き込まないことを 確実にします たとえば 完了ハンドラを活用し― 共有バッファを エンコーディングスレッドに 更新するのが安全になるまで 待つことができますが― 私たちが待ち時間を回避した 方法をお見せします 完了ハンドラは維持し かつ余分のバッファを― リングバッファに追加して 待ちを避けました 下の図は紫色で 余分な バッファを示しています メモリの消費は 離散GPUと変わりません しかしメモリを節約する 必要があり― CPUの待ち時間が フレーム レートに影響しない場合は― 3つのバッファのみを 使用できます では 共有バッファと プライベートバッファの― 作成数を判断するための 簡単な方法を紹介します このコードスニペットでは 初期化の際に 共有および― プライベートバッファ数を 選択する方法が確認できます デバイスを作成したら― そのデバイスが統合メモリを 装備しているか 確認し 余分の 共有バッファを作成するか プライベートバッファを 使用するかを決定します この余分なバッファは データ競合状態を 避けるために使用する 完了ハンドラの― 待ち時間による影響を 減らすのに役立ちます これで前のフレームの フラグメントワークロードと 次フレームの頂点ワークロードとの オーバーラップを確認でき シーンによりますが これで全体的に 1~2ミリ秒削減できます もちろん このアプローチは― この例でお見せした 定数バッファデータに加え CPUからGPUに転送した すべてのバッファデータに 適用できます ではおさらいしましょう Larian Studiosは 以下の最適化を適用して― パフォーマンス目標を 達成しました 最も高価なシェーダを 最適化してバブルを削減 可逆圧縮を選択し帯域幅を改善 頂点とフラグメントワークロードの オーバーラップで GPUの活用を向上し フレームのオーバーラップを 妨げるリソースの依存関係を 確認しました 最適化を完了した時 Larian Studiosは― パフォーマンス目標の 達成だけでなく ゲームの― フレーム時間を 33%改善しました それでは 「メトロ・エクソダス」で― 異なる一連の最適化を 紹介します 「メトロ・エクソダス」は このクリップを見ても わかるように 壮大なストーリー展開と― 高水準の視覚効果が 特徴的です 私たちが推奨した最適化を 導入することで― 4A Gamesは パフォーマンス 目標を達成しました それではゲーム内の シーンを― 見てみましょう このゲームはカスタム ワークフローを使用し レンダリングコマンドを Metal APIコマンドに変換します クロスプラットフォームの ゲームでは一般的なことです 同社が使用する変換レイヤは Metal向けに― 最適化されましたが 2つの複雑なシステムが― 合わさると問題が起こり― プロジェクト目標を 達成するために― 追加の微調整が 必要になりました 前回のゲームのように まずはフレームが― どうレンダリングされるかを 調べました 現代のレンダラーには異なる 技術が使用されているので― ハイレベルのフレームグラフの 把握から始めました ここでもGPUトレースを見て 分析を始めます ゲームパフォーマンスの 有益な洞察を得られます では デベロッパの パフォーマンス目標に― 達していない GPU時間から始めます 最も時間を消費する シェーダか― パイプラインを 見つけましょう これを行うには パイプライン状態別に― 分類し 最も高価なものに 注目します 少し統計を見てみましょう 合計と比べると ALU命令の数値が高く― 数学重視の シェーダなのがわかります またシェーダが使用する レジスタの数も― かなり高いことがわかります 特定のシェーダが使用する レジスタの数は― 実行中のワークロードの スケーリングに影響します この数値が高いほど GPUによる並行した― 作業の実行が減ります この例のSSAOのような 複雑なシェーダが― 多くの計算やレジスタを― 必要とするだけの場合も ありますが― コンパイラ設定が 生成された命令や レジスタの割り当てに 影響を及ぼす場合もあります シェーダコンパイラの オプションを見てみましょう 実は このシェーダは Fast mathフラグが― 無効で コンパイルされていました Fast mathは シェーダコンパイラが― さまざまな命令を 最適化するのを可能にし― Metalではデフォルトで 有効になっています しかし あるケースでは― たとえばカスタムシェーダ ワークフローを使用すると― このフラグが 無効になってしまいます この場合では 4A Gamesが コンパイラの呼び出しに― 使用する変換レイヤが Fast mathを使用しない― デフォルト動作に 設定されていたのです では Fast mathとは 何なのでしょうか? Fast mathとは 浮動小数点演算の― 一連の最適化で― 速度と正確さを交換します たとえば 結果や引数には 非数 無限大 負のゼロがないと 推定できます Fast math最適化は― 代数的同値変換も適用でき― 浮動小数点結果の精密性に 影響を及ぼす場合があります しかし ほとんどの場合 Fast mathはゲームには 最適な選択肢です これは特にALU向けの ケースで― パフォーマンスを改善します 皆さんにはコンパイラ オプションを確認し― シェーダが先述のものに 依存していない場合は― Fast mathが有効かを 確認することを推奨します
Fast mathフラグは フロントと― バックエンドのコンパイラ レベルで動作します シェーダソースを 構築する際 フロントエンドのシェーダ コンパイラは Fast math機能を選択し 中間コードに使用します これがバックエンドの コンパイラにより最適な― GPUマシンコードを 生成するよう示唆します これを見ると 左の命令と― レジスタの数が このシェーダを再び― コンパイルした後に 改善したのがわかります 変換レイヤの動作を変更し― すべてのシェーダに Fast mathを有効にすると 内蔵のゲームベンチマークを 使用して― フレーム時間を 21%削減できました 次は冗長バインディングに ついて お話しします サマリーページに戻り― APIインサイトを見ると フレームのレンダリング中に 多くの冗長バインディングが 見られます テクスチャ バッファ サンプラー などのリソースか 深度ステンシルステート ビューポート構成などの― レンダリング状態を 意味します 反復的なリソースの バインディングは― エンコーディング時間に 悪影響を及ぼす場合があり 冗長なレンダリング状態も GPU時間に影響を及ぼします Metal System Traceの GPU時間と― エンコーディングを 見てみましょう 特定のフレームの すべての命令が― コード化されるまで 8.5ミリ秒かかり― GPUがこのフレームを レンダリングするまで― 約22ミリ秒かかります 冗長なバインディングの 原因を調べたところ― それを削減するには 変更レイヤを― 変更できることを 発見しました では擬似コードを使い 冗長なバインディングを― 確認し削減する方法を お見せします テクスチャをエンコーダに 直接バインディングせず― プリキャッシュし 変化した場合のみ バインディングします APIとの交信を最小限に するには 呼び出しが1回の テクスチャは 1つずつ ループに設定する代わりに― setFragmentTexturesの メソッドで設定します さらに他のシェーダや バインディングタイプ つまりバッファ サンプラー レンダリング状態などに 同様のアプローチを 用いることができます Metal System Traceでは どうなるか見てみましょう 4A Gamesは エンコーディングの時間を シーンにより 30%~50% 削減できました 変換レイヤが同じリソースや レンダリング状態を繰り返し― バインディングしなく なったからです しかしGPU時間も 最大3ミリ秒― 削減され 全体的に― ゲーム内ベンチマークで 速度が15%上昇しました 冗長バインディングの警告が 少ない場合は― 問題はありませんが 数百から数千ある場合は― かなりの違いが見られます 冗長バインディングの回避で 平均フレーム時間を― さらに15%削減できました この2つの改善により 4A Gamesは― パフォーマンス目標を 達成しました Apple GPU向けに 「メトロ・エクソダス」を 最適化した方法を おさらいしましょう まずシェーダにカスタム ワークフローを使用する場合 コンパイラ設定を確認して MetalのAppに 最良のオプションを 使用しているか確認します Metal Debuggerに 冗長バインディングの― 警告が頻繁に表示される場合 これまで紹介した― エンコーディングと GPU時間オーバーヘッドを 削減する技術を エンジンまたは― 変換レイヤに適用します では これからDustinが― 「Divinity: Original Sin 2」と― Xcode GPU Timeline 機能についてお話しします Jonathan ありがとう 私の名前はDustinです Appleの― GPU Softwareチームの一員です 本日は Larian Studiosの人気ゲーム 「Divinity: Original Sin 2」の 早期ビルドの 最適化の実演デモを行います 昨年 LarianはiPad向けに 世界で絶賛されている― ロールプレイングゲーム 「Divinity」の発売を 発表しました 昨年1年間 Larianは ゲームがApple GPUで― うまく動作するよう 最適化に取り組みました プレイするのが 大変面白いゲームです LarianはMetal Debuggerと Metal System Traceの すばらしい一連のツールで これらの結果を出し― Xcode 13は新しい GPU Timelineの追加で― 今年さらに強化されました ではまず私が先ほど捉えた 「Divinity」の フレームを見ることから 始めましょう これはサマリーページで フレームの概要が― 含まれており― ゲームのデバグと最適化に 役立ちます サマリーページから GPU Timelineを含む― Metal Debuggerで 提供されている― すばらしいツールに 移動でき― この新しい パフォーマンスページで― ツールにアクセスできます ではこれからアクセスします 新しいGPU Timelineを 紹介します TimelineはApple GPUの― 独特なアーキテクチャに 合わせて設計されており― GPUパイプラインステージを 並行で実行できます パフォーマンスを 最大化するには オーバーラップを最大化し パイプラインを多忙にします Timelineで それを簡単に確認できます Timelineは2つの セクションから成ります 上部はGPUセクションで― 各パイプラインステージの 異なるトラックで構成され どのステージがアクティブで 並行して実行されているか 簡単に確認できます その下にカウンター セクションがあります シェーダの占有率 帯域幅 パフォーマンスリミッタなど 精選された重要な数字が 含まれており― GPUシステム パフォーマンスが どう変化するか 詳細な洞察を得られます GPUトラックの エンコーダは1クリックで 色々な役に立つ情報を 提供してくれます Render Encoderを選択すると― Timelineのサイドバーが 表示され これには― 現在選択したアイテムの 追加情報が含まれています この場合 サイドバーには テクスチャ詳細 ロード/保管アクション ドローコール数など レンダーパス情報が 含まれています レンダーエンコーダは― 2つのシェーダ ステージから成り 頂点とフラグメント ステージも強調されています フラグメントトラックを 選択した場合 Timelineにすべての エンコーダが含まれます これは 時間別にソートできます またフラグメントトラックを 拡大すると― 実行中にエンコーダが 使用した― すべてのシェーダを 表示することができます 長期的なシェーダや 他のシェーダと並行で 実行するシェーダを 特定することができます フラグメントトラックには― ロード/保管アクションの 2つの追加のトラックがあり これによりGPUが いつ ローカルと― メインメモリ間の付属の テクスチャを読み込み 保管するかを確認でき 帯域幅の 使用削減に考慮すべき 重要なこととなります シェーダを選択すると Timelineでアクティブな すべてのリージョンが 強調され― コンパイラ統計と ランタイムパフォーマンス メトリクスから 詳細を学ぶことができます Shader Timelineを 拡大すると 各シェーダを それぞれの トラックで確認でき― GPUワークロードの流れと シェーダ実行の順序を 把握するのに役立ちます 新しい GPU Timelineについて 活用方法を学んだところで― GPU Timelineを使用し― 簡単にボトルネックを 見つける方法を紹介します シェーダの パフォーマンスは レジスタプレッシャーにより 機能が低下します これが起こるとGPUは 高速レジスタメモリを失い メインメモリを使用します 高度の ALUリミッタだけでは― ボトルネックを 検知できません 数学が中心なシェーダ なのかもしれません でもシェーダの低占有率と 組み合わさった場合 レジスタプレッシャーを 経験している場合があり― シェーダの動作が 遅くなります これを本日のデモで うまく強調するため― ALUトラックとシェーダ 占有率トラックを― 左の“+”ボタンを クリックして― Timelineの上部に ピン留めします
この2つのトラックを調べて 最初に気づいたのは― ALUが急上昇している この部分で 同時にシェーダ占有率は 低下しています Timelineでこの領域を強調して― 実行にかかった時間を確認します これを行うと サイドバーのカウンターは 選択した領域に基づき 動的に更新します この領域では実行に 約3.7ミリ秒かかっています 拡大して さらによく見てみましょう どうやら問題は 環境遮蔽パスの― 最初の4つのエンコーダに 関連しているようです Shader Timelineを見て― どのシェーダが 使用されたか確認します このシェーダのみが 使用されているため― これに関連がありそうです ランタイムパフォーマンス メトリクスによると― ALUだけでなくfloatも 多く使用しています それでは― 浮動小数点トラックを 見てみましょう このトラックに カーソルを重ねると― このシェーダは F32のみを使用しています F16は0%です Timelineから 右クリックで― シェーダソースに移動し シェーダを開けます ソースエディターでは デモ用に簡素化された― シェーダソースが 表示されています シェーダプロファイラを 使用すれば― 各行のコストを 確認することもできます 円グラフにカーソルを 合わせると― ALUとfloatの両方が 大量なため― この関数が レジスタプレッシャーを― 引き起こしていることが 確認できます このような状況では F16が候補となります F32の完全精度を必要としない場合に 2倍のレジスタを提供してくれるので レジスタプレッシャーの 削減に役立ちます Metal Debuggerは ソースコードを直接 ソースエディターに 更新するのに役立ちます ここで F32とF16の 組み合わせを使用する― 最新版のシェーダを 使用する変更を行います この変更を行った後 下部にある ボタン をクリックすると― 更新が始まり シェーダは 再コンパイル リプロファイルされ 各行のコストも更新されます Timelineに戻り 変更による影響を 確認しましょう 最初に確認したいのは― 環境遮蔽パスの 最初の4つの― エンコーダにかかる 時間です
この領域では実行に約2.6秒 かかっています 今行った変更により― シェーダの実行時間は― 1ミリ秒以上 30%削減され 大きく改善されました 先ほどの カウンターを見ると― ALUはまだ高いですが― これは予期していたことです しかしシェーダの レジスタプレッシャーは― 低下し シェーダ占有率は― 約2倍改善しています F32とF16の組み合わせで これを達成しました ご覧のとおり 浮動小数点トラックを 使用しています GPU Timelineで 問題を― 簡単に特定し 問題が存在する場所に― 移動し 解決することができました GPU Timelineは シェーダパフォーマンスの 問題特定だけでなく― メモリ帯域やその他の問題の 解決に役立ちます この新しいGPU Timelineの デモをお楽しみいただき ゲームを最適化して Apple GPUで― よりよく実行するための さまざまな方法を― すでにお考えであることを 願います では残りのWWDCを お楽しみください ではJonathan すばらしい デモをありがとうございます そして ご視聴ありがとうございます Larian studiosおよび 4A Gamesと協働し― Apple GPUの機能を 活用した方法を― 共有できたことに感謝します 可逆圧縮からワークロードの オーバーラップまで さまざまなパフォーマンスの 改善を提供してくれます Metal System Traceや Xcodeの 新しいGPU Timelineは ゲームの改善に 非常に役に立つでしょう 最後にお伝えしたいのは レンダリングの詳細な検証は 高度に最適化されたゲームを 提供する上で必須です そして私たちのツールが それをお手伝いします 詳細については― 関連のセッション 今年のWWDCから “Metalのデバッグ プロファイリング アセット作成ツール”をご覧いただくか― WWDC20の“GPUカウンタによる MetalのAppやゲームの最適化” をご覧ください ありがとうございました さようなら [音楽]
-
-
15:24 - Pseudocode to choose shared and private buffer count
// Number of frames application is processing static const uint32_t MAX_FRAMES_IN_FLIGHT = 3; uint32_t sharedBuffersCount = 0; // Number of buffers with MTLStorageModeShared to create uint32_t privateBuffersCount = 0; // Number of buffers with MTLStorageModePrivate to create if (device.hasUnifiedMemory) { // Use extra buffer to reduce impact of completion handler sharedBuffersCount = MAX_FRAMES_IN_FLIGHT + 1; privateBuffersCount = 0; } else // GPUs with dedicated memory { sharedBuffersCount = MAX_FRAMES_IN_FLIGHT; privateBuffersCount = 1; } // Create shared buffers MTLStorageModeShared // If applicable, create private buffer
-
21:40 - Pseudocode to avoid redundant bindings
void Renderer::SetFragmentTexture(uint32_t index, id<MTLTexture> texture) { if (m_FragmentTextures[index] != texture) { m_FragmentTextures[index] = texture; m_FragmentTexturesChanged = true; } } void Renderer::BindFragmentTextures() { if (m_FragmentTexturesChanged) { [m_RenderCommandEncoder setFragmentTextures:m_FragmentTextures withRange:NSMakeRange(0, m_LastFragmentTexture + 1)]; m_FragmentTexturesChanged = false; } }
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。