Direct3D11 マルチスレッドのための機能

PC もマルチコア CPU が当たり前となり、マルチスレッド化がパフォーマンス向上の
鍵となっています。
Gamefest2008 の D3D11 関連のスライドによると、Direct3D11 ではようやく
本格的にマルチスレッドへの対応が行われるとのことです。

Gamefest 2008 Presentations

これまでは、原則としてレンダリング用の単一のスレッドがリソースアクセスや
描画を行う必要がありました。

D3D11 では非同期のリソース読み込みや複数スレッドからの描画が行えるようです。
またこれらに対応したため、個別に作成された Display List を使った描画も
実質的にできるようになっています。
ゲーム専用ハードでは当たり前のものですが、PC 側にフィードバックされる形と
なったようです。

概念としては現在の Device Interface (ID3D10Device) が、複数の Interface に
分割されます。

 (1) Device
 (2) Immediate Context
 (3) Deferred Context

リソースの作成は従来通り (1) の Device を通して行います。
Thread 対応となり、複数のスレッドで呼ばれても問題が起こりません。

(2) の Immediate Context は従来の ID3D10Device 等での描画に相当し、
レンダリング用スレッドで命令をすぐに発行できます。

(3) の Deferred Context は他のスレッドで描画命令を使用する場合に用いられます。
描画命令はバッファリングされます。いわば内部的に Display List が作られ、
最終的にレンダリングスレッドで Immediate Context と同じように描画命令を発行
できます。
API によっては DispalyList へ乗らないものもあるので、多少の制限は存在します。

基本的に各種ステートがそれぞれの Context 間で干渉することはないようです。
独立して管理し、Display List の描画を行ったあとにステートをリセットした方が
速いとのこと。
この辺の仕組みが具体的にどのような実装になっているのかまだわかりません。

D3D11 は上位互換性があり、D3D10 用の今の GPU でも動作することになっています。
現在の GPU ドライバはスレッド対応になっていないため、呼ばれた API を
バッファに記録して擬似的に Display List をエミュレートする形になるそうです。

リソースアクセスも、使用できるものの lock の粒度が荒くなるため効率は
それなりに落ちるとのこと。
将来的には Direct3D10 世代の GPU でも、ドライバの更新によってスレッド対応化が
行われてパフォーマンスが改善されるようです。

ちなみに現在の D3D9~10 でも、デバイス作成時のフラグで API 呼び出しを
Multi Thread 対応にすることが出来ました。
これは古いやり方で作られており効率悪いため、指定しない方がよいとのことです。

これまでは、使用する Direct3D SDK を次々と乗り換えてきたのは GPU の新しい
機能を使うためであって、GPU の都合によるものでした。

今回の更新は、今のマルチコア CPU を最大限活用するためにも必要となるかも
しれません。

関連エントリ
Direct3D11 テセレータとシェーダー
Direct3D11 のパイプライン
Direct3D11 Compute Shader など
Gamefest2008 と Direct3D 11