MDX Performance

とりあえず外の評価から.最後の方で持論でも.
残念ながら Managed DirectX (以下 MDX) と Unmanaged DirectX のパフォーマンス比較で「これぞ」というほどの資料は未だに見たことがありません.やや古いですが GameDev.net の以下の議論あたりは参考になるかと思います.擁護派の人間は概ね Native の 95% 以上の性能は確保できると言っているようです.
http://www.gamedev.net/community/forums/topic.asp?topic_id=267147
他には ".NET Undocumented" の「NET vs Native Performance」にて,ここでも Native よりも 5% 遅いという数字が出てきます.
http://wesnerm.blogs.com/net_undocumented/2004/09/net_vs_native_p.html
(追記)また Intel Resource Centers で公開されている資料では Native の 98% という数字が出てきます.
http://www.intel.com/cd/ids/developer/asmo-na/eng/segments/games/57590.htm?page=3
ただしここで言われている WinForms のオーバーヘッドについては,この半月後にリリースされる「DirectX 9.0 SDK Update - (Summer 2004)」で一定の回答がなされています.この SDK から,Form クラスを利用せず P/Invoke を利用して自前の Message Pump を実行するというサンプルフレームワークが付属しました.Form クラスのオーバーヘッドについては以下参照.
http://weblogs.asp.net/tmiller/archive/2003/11/07/57524.aspx
http://weblogs.asp.net/tmiller/archive/2003/11/24/57532.aspx
また,MDX の作者の Tom Miller 氏ですが,折に触れては「パフォーマンスに配慮したこと」と述べられています.
http://members.gamedev.net/managedworld/articles/interviews/tommiller.html
http://weblogs.asp.net/tmiller/archive/2003/12/23/57538.aspx
さてここから持論.
.NET FrameworkWindows 95 サポートがないこと及び Windows 9x サポートに不安があることから,これらをターゲットとしたい場合 MDX はいきなり選択肢から外したいと思います.
MDX の実装についてですが,MDX の実態は Managed C++ で書かれたかなり薄い Managed Wrapper です..NET らしい付加機能はほとんどありません.C++ 用の D3DX の機能についても薄くラップするに留まる部分が多く,MDX 独自のユーティリティクラスはさほどありません.例えば以前 D3DX 関数が UTF-8エンコードされたテキストをきちんと読み込めなかった時期には MDX も同様の制限を受けていました.
基本的には Unmanaged DirectX の各 interface ごとに MDX には Managed Wrapper クラスが存在します.いくつかの Wrapper クラスは内部に状態を持つため,Unmanaged Pointer 1 つに対し異なる状態を持った Wrapper のインスタンスが存在し,ライブラリの整合性をやや失わせる要因となっています*1.「DirectX 9.0 SDK Update - (Summer 2004)」以降は (Unmanaged) Native Pointer を完全に露出させたため,その気になれば直接 Unmanged DirectX Function をコール可能です.全体としては,誰が作ってもこの程度のオーバーヘッドは出るだろうという意味において,MDX のオーバーヘッドは比較的少ない方だと思います.
アプリケーション全体のうちどこに Managed / Unmanaged の境界を設定するかは興味深い問題です.メソッドコール回数 / データマーシャリング量から言って,DirectX の真上にその境界を持ってくるのは悪くない選択だと思います.そもそも現在の 3D API の実装では,使用するデータの大半はライブラリ内に存在し,データ操作やProgrammable Shader のみが主にやりとりされる構造をしています*2.MDX は主にこのパッチ処理の発行にオーバーヘッドをもってきたわけで,最大トランザクション/秒は確かに落ちているかもしれませんが,元々の DirectX の構造から言ってオーバーヘッドトータルの処理量は少なくて済みそうです.いずれにせよ確定的なデメリットというものがあるとしたらここでしょう*3
一方,Unmanaged の方が効率の良いコードが書きやすい部分――特に数値演算系――についても注意が必要です.個人的な経験では,特に何も考えずにコーディングすると一部の値型――行列やカラー構造体――がループ処理で大量に生成/破棄され,ボトルネックとなることがありました.とはいっても IL のコードは素直なので,ボトルネックはプロファイラで簡単に発見できます.MDX を利用する場合は,(少なくともプロトタイプとしては) アプリケーションのほとんどの部分を Managed Code で実装することが予想され,DirectX の知識だけでなく .NET の最適化テクニックで大きくパフォーマンスに差が付くと予想されます.
というわけで,MDX を利用してゲームを書く場合,DirectX 呼び出しにかかるオーバーヘッドだけでなく,ゲームエンジンC# で記述することによる影響も気になります.余裕があったら C# で書かれた物理演算ライブラリのパフォーマンスでも調べてみたいところです..NET で書かれた物理演算ライブラリを探す場合,以下のサイトがよくまとまっています*4
http://www.thezbuffer.com/
場合によってはエンジン部分の一部またはほとんどについても Unmanaged Code に切り出すメリットがあるでしょうが,そういう場合の境界設定は腕の見せ所でしょうね.逆にゲームのスクリプト部分のみを C# に置き換えるというのもひとつの選択でしょうけど,その程度なら LUA で十分だったりするかもしれません.ただまあデバッグ環境は恵まれてるかなぁ.

*1:http://www.gdncom.jp/general/bbs/ShowPost.aspx?PostID=14885

*2:なんとなくデータベースアプリケーションに近い気がしています

*3:実際のところ最近は CPU の処理能力とバッチ発行量が最大スループットを決めるシナリオについて言及されることが多く,このようなシナリオにおいてのパフォーマンスダウンは数字として無視できない程度になるかもしれません.また,DirectX では Push Buffer といった DirectX 内部エンジンの改良次第でまだまだ性能の伸びる余地があるとも言われています.詳しくはGDC 2004 の以下の資料あたりを参照のこと.「DirectX アプリケーションのパフォーマンス チューニング」の前半部分.「高度なライティングと DirectX Graphics の将来展望」の 39 ページ.

*4:そもそも MDX 全般に関して最もまとまったニュースサイトのひとつかもしれません.