-
Metalシェーダのデバッグとプロファイリング
Metalには、シェーダの動作を分析し、パフォーマンスを最適化するためのパワフルなツールが用意されています。このセッションでは、Xcodeの新しいジオメトリ表示機能を使った、Vertexステージに関する問題のトラブルシューティング方法について説明します。シェーダデバッガを使うと、Vertex、Fragment、Computeのシェーダの実行を行ごとに確認することができます。GPUへの負荷の分析に関する詳しい情報や、A11 Bionicのためのシェーダプロファイラの強化点についてご確認ください。
リソース
- Analyzing resource dependencies
- Debugging the shaders within a draw command or compute dispatch
- Optimizing GPU performance
- プレゼンテーションスライド(PDF)
関連ビデオ
WWDC20
WWDC18
-
ダウンロード
(拍手) こんにちは ここに立てて光栄です 始めましょう シェーダは グラフィックスの要であり ゲームやアプリケーションの 見栄えをよくします 膨大な計算を実行する環境で シェーダを扱うのは厄介です 開発の過程で 失敗することも多く うまくいったとしても 処理速度も問題です 私はアルプ Metalシェーダのデバッグと プロファイリングで― 役立つツールと ワークフローをご紹介します
フレームワークや 言語だけではありません Metal Performance Shaders MetalKitに加え― 開発過程を支援する ツールもあります
Instrumentsに統合された Metal System Traceが― CPUやGPUの並行処理の 可視性を広げます アプリケーションの パフォーマンスも高まります
しかし今日 注目するのは Metal Frame Debuggerです
Metal Frame Debuggerを使えば ゲームのフレームや― アップロードやAPIコールの中から Metal処理を見つけ出します
さらに プロファイリング機能により GPUカウンタやパイプラインの 統計にアクセスできます Xcodeに組み込まれており Metalワークロードの― プロファイリングと デバッグが1カ所でできます
今年はさらに 有用な機能が いくつか加わりました Dependency Viewerで エンコーダが可視化され― リソース使用における 連携の様子が分かります ワークロードを導く 優れたツールで― フレーム作成の過程が 理解できます
明日10時のMetalゲームに 関するセッションでは― Dependency Viewerの 話をします でも今日のテーマは Geometry Viewerと Shader Debuggerと Shader Profiler 日々の作業に役立つ ワークロードをご紹介します
グラフィックパイプラインの 第1段階である― 頂点ステージでの失敗は 致命的です
だからシェーダのデバッグに 手をつける前に― 頂点の問題を排除します
頂点ステージではいくつか チェック事項があります 主に頂点入力 インデックス 頂点出力です 昨年 我々がXcode 9で 導入した入力属性ビューでは 全データを表形式で 見ることができます それでも元の3Dを 参照しなければ
視覚データの デバッグは困難です だから今年は すべてのデータを統合し― 視覚化し確認できる場を 作りました ではGeometry Viewerです
(拍手) 変換後の頂点データを 3Dで視覚化し― 頂点出力が実際に どう見えるか示すツールです データ入力 インデックス 出力の情報が分かるので― 元の3Dを参照できます ドローコールごとに 提供されるので― 頂点における問題のすべてを 1カ所で確認できます
頂点に関する3つの 一般的な問題を取り上げ― Geometry Viewerの 使い方をご紹介します
ドローコールを出し 木を描こうとしています 三角形の頂点のいくつかが 画面外にあり― 三角形がゆがんでいます Geometry Viewerで この三角形をクリックします 頂点の入出力に関する すべてのデータが― 画面下のビューアーに 表示されます
2つ目の例も 同じドローコールです でも今回は木はありません Geometry Viewerと Freeflyカメラを使って―
画面上に現れないのも 納得ですね Geometry Viewerなら 検出は簡単です 最後の例では3Dで三角形が できないことすらあります これらのデバッグは厄介です
複数の頂点が同地点に 向かうと三角形が作れません あるいは頂点の出力に 無限数や非数があると GPUはこれを受け付けません Geometry Viewerはこれらを 見つけ出してくれます
不正な三角形を検出しました クリックすると データが見られます このデータによれば 頂点の2つが― 原点に向かっており 三角形が変形しています
このように Geometry Viewerは― ジオメトリ関連の問題を すばやく調べるツールです 入力に問題があれば モデルをチェックしますが 出力に問題があれば デバッグが必要になります 次に移ります
Shader Debuggerです シェーダのデバッグは難しいです コードが複雑で ベクトル演算が多いからです シェーダコードは フレームごとに― 何百万回も実行され 並列処理されます
Book of the Deadの デモを見てみましょう 今週前半の基調講演でも 登場しましたね このシーンの 1フレームで― 1000万の頂点シェーダが 起動します すべてのパスの各フレームの ピクセル数は6000万
シェーダに 問題がある場合― 原因となっているシェーダや コードを特定するのは困難です シェーダのデバッグを 支援するための― 新たなShader Debuggerを ご紹介します
Shader Debuggerは Metalシェーダ用ツールです 数千ものスレッドを 即座に可視化します
柔軟な設定ができるので ブレークポイントなしに― 実行することができます
Metal Frame Debuggerに 組み込まれており― シェーダのデバッグに必要なものが すべてそろいます では同僚のハビエルが Shader Profilerを― ご紹介します ハビエル (拍手) ありがとう アルプ 皆さん こんにちは
今日はカッコいい水の シミュレーションをします しかしジオメトリに 問題があります 新しいShader Debuggerを ご紹介し― ジオメトリの問題を解決する 方法をお見せします
まずは フレームのキャプチャです デバッグバーのキャプチャ ボタンをクリックします
ジオメトリに問題があるので Geometry Viewerで―
平らであるべき水面が 崖のようになっています 不正な三角の1つを クリックします 底辺の不正な頂点を 詳しく見ていきます この表を使えば簡単です
この三角の頂点は ほぼ同じ値になっています Y座標はまったく同じです 入力値は正しいようです
3Dビューで出力に 不具合があるのは― 頂点シェーダに 問題があるということです Shader Debuggerで この問題を修復します
Shader Debuggerでは ソースコードに沿って― 修正された全変数に アクセスできます 変数の詳細が 知りたければ― この詳細ボタンを クリックします
ソースコード言語で すべての変数値が表示されます デバッグ対象の 三角について― 全頂点の変数の値も 表示されます
デバッグナビゲータでは 履歴も見られます 実行した内容が 最初から最後まで見られます 矢印キーを使うだけで コードも簡単に処理できます
ご覧のとおり ナビゲータの実行中は― ソースコードが ハイライト表示されます これは逆方向にも作用します ソースコードの1行を選ぶと ナビゲータ上の位置が定まります
画面下の変数ビューで 対象の変数すべてに― いつでもアクセスできます
変位ベクトルの生成で 水の計算が行われ― 後で最終位置に加えられます 詳細ビューで変位ベクトルの 詳細を見ます
ここで分かるとおり― デバッグ中の頂点の右座標は 大きなマイナスの値です しかし他の正しい頂点は プラスです つまり問題は 変位ベクトルの計算方法です デバッグナビゲータで 何が起きているか調べます
コードを読むまでもなく― 問題があることが分かります 変数の1つが 非数を示しています これが障害だと思われます 原因を調べましょう ここをクリックすると 演算の数値がマイナスで― それが問題を 起こしているようです 問題の原因が分かりました この2つの行を 切り替えれば― マイナスの数値が 修正されます これでシェーダが 変更されました リロード変更ボタンを クリックし変更します
シェーダのリロードが 新たなシェーダで行われ― すぐに結果が チェックできます
ご覧のとおり 水面が滑らかになりました デバッグバーの継続ボタンを クリックしチェックします
正しいシミュレーションが 完成しました (拍手) 今ご紹介したのは フレームキャプチャの方法 Geometry Viewerを使い 不正な頂点を見つける方法 そして新しいShader Debuggerで 頂点シェーダを修復する方法です アルプにマイクを戻します (拍手)
ありがとう ハビエル Shader Debuggerを ご紹介したところで― デバッグニーズのための 使い方を詳細に述べます でも最初の問題は― Shader Debuggerに どう入るか
フレームをキャプチャして 最終コールで― ドローあるいはディスパッチ コールを選択します デバッグバーの シェーダボタンを起動すると Shader Debuggerに アクセスできます ビューが現れたら スレッドを選択します
シェーダのタイプに応じて その後の作業は変わってきます フラグメントシェーダなら ピクセルインスペクタで― デバッグしたいピクセルを 選びます 頂点シェーダなら Geometry Viewerで― 問題の頂点を選びます
計算するならコントロールで 対象のスレッドを選択し― デバッグボタンを クリックするだけ Shader Debuggerなら― 気になっている変数を 簡単に確認できます その変数のソースラインに アクセスするだけ ブレークポイントもなく コードも不要 修正された変数の値が サイドバーに現れます
デモで見たとおり無限値が ハイライト表示され― 誤りが簡単に分かります サイドバーのボタンで 詳細ビューが表示され― 変数の全情報が分かります
ソースコードにある変数なら どれでも― 値を即座に 知ることができます この例のように テクスチャの― サンプリングでも役立ちます 正しいテクスチャが すぐにチェックできます
CPUデバッガと同様に 変数ビューにアクセスし― 全変数の表示もできます
変数の確認はシェーダの デバッグの核ですが― すべてではありません コードの実行順序も 知りたいですね これも簡単にできます
Shader Debuggerの デバッグナビゲータに― 選択したスレッドの ソースラインが表示されます
どのラインを 選択することもできます カーソルキーを使用して コードの順番を チェックできるのです
逆戻りも可能なので― シェーダのデバッグの 性能が高まります 不正値を持つ 変数を見つけ― 誤りと原因を追って 過去にさかのぼれます
気になることを何でも フィルタできます 関数コール 変数 リソースが フィルタの対象です シェーダコードは他の ファイルでも使われますが フィルタを使う場合は シェーダの対象だけ 対象の限定に効果的です
1つのスレッドのデバッグは これでよさそうです しかし別のスレッドは?
選択した 最初のスレッドから― 他のスレッドにも アクセスできます つまり選択した頂点の プリミティブが得られます フラグメントでは 選択したピクセル周辺
計算では選択したスレッドの グループの情報が得られ― スレッドグループメモリに 絡む変数にアクセスできます
コードが数百万もの ピクセルを実行する際― ピクセルごとに1つの変数が 常に役に立つわけではありません 例をお見せします 勾配を計算していますが 値が確定せず― この勾配値が適切なのか どうか分かりません クリックすれば 詳細ビューで― 自分のピクセル周辺の 勾配値を確認できます きれいな勾配ではないため 値が正しくないことが分かります
このように詳細ビューは シェーダの理解を助け― 値が正しいかどうかの 判断に役立ちます
すぐに他のピクセルに 移動し― 変数が適切かどうかを 判断できます
ピクセルの正否が明らかな 場合の比較に有用です すばやく切り替え ピクセルの動作を確認できます
切り替えで実行履歴と 変数ビューが更新され― 選択したスレッドを 完全にデバッグできます
詳細ビューの 右側のマスクも有用です どのスレッドが 同じコードを実行したか 常に表示してくれます
この例では対角線で 区切られた部分です スレッドのおよそ半分が 同じコードを実行したことが はっきりと分かります
次はフラグメントシェーダ 詳細ビューで 問題を修復します 再びハビエルの登場です ハビエル (拍手) ありがとう
先ほどはジオメトリの 問題を解決し― プロセスとエフェクトに 目を向けました 結果が予想と違ったので― フレームキャプチャで デバッグしました
このビューを見ると― ハイライトの下に 暗い部分ができていますね Shader Debuggerで 修正します
ピクセルインスペクタを 呼び出し― デバッグしたいピクセルを 選択します 例えば このピクセルを選択して― デバッグボタンを押し Shader Debuggerを開始
ハイライトは3段階で 生成されています 詳細ビューで 現状を把握します 最初にこれを見ましょう
オリジナルカラーから サンプルを作成しています 正しいようです 次を見ましょう
ハイライトが1方向に 集中しています 詳細ビューを開き 結果を見ます
こちらの詳細ビューを見れば 分かるように 下のほうに すでに暗い部分があるので このハイライトの集中が 問題のようです このように 詳細ビューを使えば― コードを読まずに シェーダを理解できます
この関数は主に 何度か 繰り返すループで― マップからサンプルを 蓄積します
ループがハイライト されているので― デバッグナビゲータで 繰り返しを確認できます ソースコードに沿って 各ループの変数が得られます
ここに注目すると 繰り返すごとに― 変数が違うことが分かります
詳細ビューとこれを 合わせて使うと強力です 最終的な色の 詳細ビューを表示します ここにハイライトが 集中しています
デバッグナビゲータを使い 繰り返します 繰り返すと最終的な色に ハイライトが蓄積し始めます しかしループの最後に向け 繰り返し続けると― あるパターンが現れます その理由を考えましょう
デバッガが示すとおり ウェイトの値がマイナスです このために最終的な色が 蓄積せずゆがめられています 原因が分かったので 手早く修復します
ご覧のとおり もう暗い部分はありません 継続ボタンをクリックして アクションを見ます
ハイライトは 修正されたようです Shader Debuggerの 使い方の一例です 詳細ビューの威力が 分かりましたか アルプにマイクを返します (拍手) ありがとう ハビエル
Shader DebuggerはMetal シェーダに特化しています GPUの高度な 並行処理に対応し― バグの修正に 非常に効果的です 非数と無限のハイライトで 誤りが見つけやすく― シェーダの理解にも 役立ちます 詳細ビューを使えばコードを 読む必要はありません シェーダ開発に 良好な環境を提供します Shader Debuggerを使い―
最新ハードウェアのiOS macOSやtvOSをサポートします そしてXcode 10で使えます
(拍手) ビューアーとデバッガによる 問題の修復に続いて― シェーダの速度アップに 注目しましょう
GPUの利用環境の最適化が 重要なのは― アプリケーションの 稼働速度を高めたいからです しかし最適化を始める前に 対象を知る必要があります
GPU基盤ならMetalの ワークロードのパスが多く― どのパスに注目するかが 非常に大切です そのためにプロファイリング ツールを充実させました
GPUカウンタは パフォーマンスを高めます エンコーダあるいは ドローコールの時期を知らせ 複数のカウンタが ボトルネックを表示します
シェーダに合った コンパイルができて― 命令の種類が すべて分かります
Shader Profilerを 使えば― ドローコールのタイミング なども分かります
今日 注目するのは Shader Profilerです シェーダの最適化に役立つ ワークフローも紹介します
Metal Frame Debuggerの パフォーマンスナビゲータで― パイプラインごとに 実行時間が表示されます 最適化対象の拡張可能な すべてのパイプラインです
これを使ってドローコールに アクセスもでき― 描画中の対象を 直接 見ることができます
iOSあるいはtvOSの場合― シェーダソースで各ラインの 実行コストが分かります 時間がかかる場所が 明らかになります シェーダではラインごとです
シェーダソースで― コードを編集しリロードして タイミングの差を確認できます
Shader Debuggerを 使うこともできます このワークフローは アルゴリズムを最適化する時や コントロールフローがうまく動くか 確認したい時に使えます
Shader Profilerは シェーダの最適化に有用で― A11ではさらに効果的です
A11 Bionicチップは全面的に AppleがデザインしたGPUです 我々はシェーダの動作の 理解を支援します
A11で得られる この図に示されるのは― 実行されたラインの コストの内訳です シェーダは異なる 実行ユニットで構成されます 1つを酷使すると それが障害になり得ます ALUとメモリの内訳を 見れば― 各実行ユニットで費やした 時間を確認できます
我々はA11で命令の精度を 高める努力をしました floatでなくhalfを使えば GPUバジェットは変わるはず
可視化できる もう1つの領域は同期です これが重要なのは― シェーダが同期を待たず フル稼働してほしいからです
シェーダコードで テクスチャやバッファを読んだり アトミックやバリアを使うと 同期に時間を要するかもしれません
だから我々は シェーダからコールする― インライン関数のコストを 可視化しました 最も高い関数を処理して 最適化することができます (拍手) AppleのA11 bionic チップは― 最高のプロファイリング データを提供します 今年 インライン関数でも 導入したのは― 各ラインのタイミング情報と 命令カテゴリ 僕はマックス 皆さんのシェーダの性能を マックスにしたいのです (拍手) 同じ水のシミュレーションを 僕のiPhoneでやってみます
パフォーマンスごとに フレームを変えてみます 時間順に並べたフレームの パイプライン一覧から― ノイズパイプラインに時間が かかっていると分かります フラグメントシェーダでは ほぼすべてが費やされています でも今年は進化しました
シェーダがコールしている 関数ごとに― 費やしている時間が 分かります
ここをクリックすると ソースコードファイルに飛び― そのラインを 調べることができます
この画面の右側に 見えているのは― この関数で使っている 時間の割合 さらに下に行くと 各ラインの時間の割合です
Shader Profilerは 最適化コードで動くので― コンパイラは命令を 再オーダーできます タイミング情報がない ラインもあります
ALUの計算に時間を 費やしています メモリとテクスチャから 読んでいます しかし心配なのは 同期に費やす時間です 特にメモリの待機時間が 長いです これはつまり GPUが データをすばやく読み込めず 別のスレッドでALUを稼働しても カバーできなかったということです 原因を探りましょう
パフォーマンスの数値から 到達したこのラインは― シェーダの全時間の 半分以上を費やしています
命令カテゴリを 再度 検証します 同期にかなりの時間を 費やしています なぜでしょう
カラーテクスチャから読んだ カラーの値を使っています ここで使うオフセットは― ノイズテクスチャから 読み込まれました つまり依存テクスチャです テクスチャからデータを 読み込むまでGPUは動きません どうすればいいでしょう ノイズテクスチャから 読み込む代わりに― GPUでノイズ値を 計算できます やってみます
シェーダを アップデートします コンパイルしたらデバイスに シェーダを送り― フレーム全体を再実行し プロファイルをやり直します 1つの変更がGPU全体に 影響する可能性があるので―
下から20超までシェーダで 3ミリ秒 費やしています 命令カテゴリも 見てみましょう
同期の合計時間が 大幅に短縮されており― GPUがしっかり働ける 状態です 要するにシェーダの障害を 検出すれば― タイミング情報から 問題の所在が分かります 命令カテゴリから 原因が分かります 以上です アルプにマイクを返します (拍手) ありがとう マックス
最後にひとつだけ 言わせてください 優れたツールを より使いやすくする情報です
オフラインでシェーダを コンパイルしていれば― オンラインの ランタイムコストは不要です オフラインで コンパイルすることにより― 新しいコンパイラで シェーダのソースを保存し― どこからでもシェーダに アクセスできます
Xcodeプロジェクトで コンパイルしているなら― ビルド設定で この選択肢を起動しましょう コマンドラインを 使っているなら― Metalコンパイラに “-MO”をパスするだけ しかしデバッグビルド内で 実行しないと― シェーダソースを含めて Appをリリースしかねません
まずGeometry Viewer 頂点関連の問題を 集中的に調べられる他― 視覚的問題を デバッグすることもできます シェーダを デバッグする前に― Geometry Viewerを まずチェックしてください
次にShader Debugger Metalシェーダの 強力なデバッガです バグを修正し シェーダを理解し シェーダを開発する際に 役立ちます
Shader Profilerで 可視性が高まり― A11 bionicチップによる GPUの動作が分かります
詳細はリンクをご覧ください 明日10時の講演は“Metal Game Performance Optimization” ゲームに共通する パフォーマンスの問題と― それを検出し修正する ツールについて話します どうも (拍手)
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。