はじめに
IntelがDirect3D12のMulti-AdapterのサンプルをGitHubで公開しています.
DX12-Multi-Adapter
https://github.com/GameTechDev/DX12-Multi-Adapter
このサンプルは,Direct3D12のMulti-Adapterを使って複数GPU環境でレイトレーシングを分散してレンダリングするということをやっています.
Multi-Adapterとは
Direct3D12では,Adapterという概念があるのですが、これがPCに搭載されているGPUを指す概念になります.PCによってはGPUの複数枚挿しやノートPCのOptimusのようにCPU統合型GPUとディスクリートGPUが両方あるような環境もあるとはおもうのですが,Direct3D12では1つのアプリケーションの中でMulti-Adapterを使うことで両方のGPUを使用するということができるようになりました.
Multi-Adapter
https://msdn.microsoft.com/en-us/library/windows/desktop/dn933253(v=vs.85).aspx
Direct3D11までは,OptimusではIntelかNVIDIAを排他的に選択して使われていたのですが,Direct3D12ではアプリケーション側の実装があれば両方を使用して計算資源を増やす…ということができます.ただ,この時に注意がいるのは,ビデオメモリの物理的な場所が違う場合にリソースが共有できなかったり,Direct3D12のデバイスはそれぞれのアダプタごとに作成されることで,それぞれのDirect3D12デバイスで生成したリソースの共有はできません.ですので,Direct3D12のCommand QueueのうちCopy Queueを使って描画とは非同期にメモリの転送を行うことでやりとりを行うことが想定されています.たとえば,GPU 0で描画したレンダーターゲットテクスチャをGPU 1のビデオメモリにコピーしてポストエフェクトをかける…なんて使い方やGPU 0はレンダリングに使いGPU 1は物理演算やサウンドなどをGPGPUするなどですね.
サンプルの結果
本題に戻りますが,上記のサンプルをOptimus搭載のノートPCで起動してみました.WindowのバーのところにフレームレートやGPUの分散具合が書かれています.
GPUの分散具合は,キーボードの上下キーで帰られるので5つのケースを見てみます.
- GeForce GTX 870M 50 %, Intel HD 4600 50%
- GeForce GTX 870M 70 %, Intel HD 4600 30%
- GeForce GTX 870M 90 %, Intel HD 4600 10%
- GeForce GTX 870M 100 %, Intel HD 4600 0%
- GeForce GTX 870M 0 %, Intel HD 4600 100%
・GeForce GTX 870M 50 %, Intel HD 4600 50%, FPS 22.60
サンプルでは,緑色のラインの上側をGeForce GTX 870Mで処理を行い下側をIntel HD 4600で処理をしています.
GPUがピクセルを50%50%で分散しています.これがまずデフォルトの状態ですね.
・GeForce GTX 870M 70 %, Intel HD 4600 30%, FPS 31.47
GeForceが70%処理を負担するケースです.このケースでは,フレームレートが10ほどあがりました.
・GeForce GTX 870M 90 %, Intel HD 4600 10%, FPS 63.99
GeForceしか動かさない場合の結果はこの次に書きましたが,今回のケースでは一番速かったです.
・GeForce GTX 870M 100 %, Intel HD 4600 0%, FPS 56.65
GeForceだけを動かしてみました.結局,負荷分散よりも同期のレイテンシでこれが一番速くなるかな?と思いましたが,最速ではなかったです.
・GeForce GTX 870M 0 %, Intel HD 4600 100%, FPS 16.78
まとめ
結果を並べてみると下記のようになりました.GPUの性能差が多いので性能差に応じて処理の割合を変えてあげるのが良さそうだと言うことはわかります.
GeForce GTX 870M 50 %, Intel HD 4600 50%, FPS 22.66
GeForce GTX 870M 70 %, Intel HD 4600 30%, FPS 31.47
GeForce GTX 870M 90 %, Intel HD 4600 10%, FPS 63.99
GeForce GTX 870M 100 %, Intel HD 4600 0%, FPS 56.65
GeForce GTX 870M 0 %, Intel HD 4600 100%, FPS 16.78
これを見ていると2つのGPUを使用した方が良いケースというのがあることにありますね.
今回の計測のケースは,NVIDIAとIntelでGPU性能が大きく異なるケースで導入してみたわけですが,性能差が小さい場合には結果は違う可能性があります.
2つのGPUの性能差が大きい場合には,同じ仕事を分散するやりかたはメリットが小さいかもしれないですね.「Multi-Adapterとは」に書いたような別々な処理を行わせた方がメリットがあるような気がしています.
まだ新しい機能ではあるので,どういう組み合わせをするとパフォーマンス向上に良いのかということについては色々と検証が必要と思います.OptimusのケースやAPU+Discreat GPUみたいなケースはわりとあるとは思いますので,色々と検証しがいのあるネタだとは思います.