NVIDIA Nsight Graphics を使ってみる

はじめに

みなさんはシェーダーのプロファイリングをしたくなったとき、どうやっていますか?
FPS 測定?でもオーバヘッドが大きいし、具体的にどこが重いのかわからない……

みたいな悩みを、 NVIDIA Nsight Graphics で解決できるかもしれません。

ほかにいい手段をご存知の方はぜひご連絡ください……

手順

まずは こちら から NVIDIA Nsight Graphics をインストールします。

インストールの待ち時間に、 Unity プロジェクトの用意をします。
対象となるシェーダーを書いて、マテリアルを作成、それを適用した Plane なり Cube なりを配置します。
カメラに写ってさえいれば OK です。むしろ余計なものがあると解析の邪魔になるので最低限で大丈夫です。

シェーダーですが、以下の #pragma が必要となるので、シェーダーコードに書いておきます。

// #pragma fragment の下あたりに入れる  
  
// デバッグシンボルを含める  
#pragma enable_d3d11_debug_symbols  
  
// shader model 6.0 を使う  
#pragma use_dxc  

これがないと詳細な解析ができません。

なお、 #pragma enable_d3d11_debug_symbols はパフォーマンスに若干の悪影響を与える可能性があります。 ( →参照 )
デバッグが終わったら消しておくのが無難です。
なんで use_dxc で SM6.0 が使えるのかは こちら を参照してください。

ビルドしたアプリを解析することになるので、アプリビルドの準備をします。

まずは Project Settings / Player / Other Settings / Rendering から Auto Graphics API for Windows のチェックを外し、一番上に Direct3D12 が来るようにします。

デフォルトの Direct3D11 だと解析に失敗します。
Vulkan でも動作しますが、デコンパイル結果などが異なり、見慣れない感じになります。
そちらに慣れている方は Vulkan のほうがいいかもしれませんが、私は DirectX をお勧めします。

そうしたら、 Windows 用にアプリをビルドします。
Development Build で大丈夫です。

ビルドしたら、 NVIDIA Nsight Graphics を 管理者権限で 実行します。
管理者権限でないと一部データの取得に失敗します。

起動したら、 Start Activity... を選んでください。

Application Executable: にさっきビルドしたアプリのパスを入れます。
そうしたら右下の Launch Frame Debugger を押します。

ここで Steam を起動していると Interfering Processes Detected と表示され、 Steam のアプリが干渉するとか言われるのですが、気にせず Keep を押して大丈夫です。

うまくいけば、ビルドしたアプリが起動します。

ここで Direct3D11on12 is unsupported みたいな警告が出ますが、とりあえずは無視しても大丈夫そうです。

アプリ上で F11 キーを押すとキャプチャできるので、押します。

すると、 Unity の Profiler みたいな画面が開きますので、解析をします。

まずは Events タブから、描画していそうなイベントを探します。
色がついているので、それを見ながら探してください。
私の場合は DrawIndexedInstanced というイベントがそれでした。検索フィルタもあるのでそれを活用すると見つけやすいかもです。

クリックすると、 API Inspector タブが更新されます。
PS (Pixel Shader) ボタンを押して Profile Shaders ↗ を押します。

すると Shader Profiler が開きます。
ここでは命令数やその内訳、かかった時間などを見ることができます。
カーソルを合わせると詳細な説明がありますので適宜見てください。

ここで、 Correlation 行に警告が出ていた場合はたぶんシェーダーコードの設定を書き忘れています。
#pragma をちゃんと書いたか確認してください。

詳しい説明は 本家の説明書 を参照してください。

ストールの種類と説明 (MIO Throttle とは何ぞや、みたいなの) は こちら

処理にかかった時間は下段の Events / GPU Duration のほか、 Events タブの GPU ms から確認できます。
Hot Spots からは重い処理がどこかを突き止めることができます。

動的にシェーダーを編集することもできる (!) らしいですが、一度編集してしまうとソースコードと照らし合わせた解析ができなくなるっぽいので、あまり有効ではなさそうです。

おわりに

シェーダーのプロファイリングなんもわからん状態だったのでとても感動して記事にしました。
とりあえず導入してみた感じですが、プロファイリングが詳しいしいろんな機能があるようなのでいろいろ触ってみたいと思います。

参考文献

User Guide — NsightGraphics 2024.3 documentation
公式のユーザーガイドです。