これは実際にはMSDNにDirectXMath Programmer's Guideで詳細に説明されています
XMVECTORとXMMATRIX型は、DirectXMathライブラリの作業馬です。すべての操作は、これらのタイプのデータを消費または生成します。ライブラリを使用するには、それらを操作することが重要です。ただし、DirectXMathはSIMD命令セットを使用するため、これらのデータ型には多くの制限があります。 DirectXMath関数を使いたい場合は、これらの制限を理解することが重要です。
XMVECTORはSIMDハードウェアレジスタのプロキシとして、XMMATRIXは4つのSIMDハードウェアレジスタの論理グループのプロキシとして考える必要があります。これらの型は、正しく動作するためには16バイトの整列が必要であることを示すために注釈が付けられています。コンパイラは、それらをローカル変数として使用するときは自動的にスタックに配置し、グローバル変数として使用するときはデータセグメントに配置します。適切な規則では、関数としてパラメータとして安全に渡すこともできます(詳細は呼び出し規約を参照してください)。
しかし、ヒープからの割り当ては、より複雑です。そのため、XMVECTORまたはXMMATRIXのいずれかをヒープから割り当てられるクラスまたは構造体のメンバとして使用するときは常に注意する必要があります。 Windows x64では、すべてのヒープ割り当ては16バイトに整列していますが、Windows x86では8バイトしか整列していません。ヒープから構造体を16バイトアライメントで割り当てるためのオプションがあります(適切なアライメントの割り当てを参照)。 C++プログラムでは、演算子new/delete/new []/delete [] overload(グローバルまたはクラス固有)を使用して、必要に応じて最適なアライメントを実行することができます。
ただし、XMVECTORまたはXMMATRIXをクラスまたは構造体で直接使用することを避ける方が簡単でコンパクトです。代わりに、構造体のメンバとしてXMFLOAT3、XMFLOAT4、XMFLOAT4X3、XMFLOAT4X4などを使用してください。さらに、Vector LoadingおよびVector Storage関数を使用して、データをXMVECTORまたはXMMATRIXローカル変数に効率的に移動し、計算を実行し、結果を格納することができます。これらのデータ型の配列に対して効率的に直接動作するストリーミング関数(XMVector3TransformStream、XMVector4TransformStreamなど)もあります。
DirectXMathは、効率的なSIMDフレンドリなコードを書くことを奨励しています。ベクタのロードや格納はコストがかかるので、データをロードし、レジスタ内で多くの作業を行い、結果を書き込む「ストリーム」モデルで作業してください。
しかし、私は、SIMDの数学やDirectXの一般的な使い方はちょっと複雑で、プロの開発者でさえも少し冗長だと言っています。だから私は、Vector3
、Matrix
クラスのようなXNA Game Studioを使って探している古典的な数学ライブラリのように動作するDirectXMath用のラッパーをSimpleMathと書いたので、すべての明示的なロード&ストアをカバーします。 SimpleMathタイプはDirectXMathときちんと相互運用するので、必要に応じてミックスして一致させることができます。
this blog postおよびGitHubも参照してください。
DirectXMathは意図的に最適化されたコードを意味する 'インライン'ライブラリであり、より大きな関数の中で値を計算するだけではなく、変数を多く渡すべきではありません。 deprecatedD3DX9
、D3DX10
、D3DX11
ライブラリ内のD3DXMathライブラリは、関数ポインタテーブルに依存しており、呼び出し規約のオーバーヘッドによって大幅にパフォーマンスが制限されています。
これらはもちろん、異なるエンジニアリングのトレードオフを表しています。 D3DXMathは、特殊なプロセッサコードパスの実行時により多くの置換を行うことができましたが、この柔軟性のために呼び出し規約と間接的なオーバーヘッドを支払う必要があります。一方、DirectXMathはSSE/SSE2(またはXbox OneのAVX)のSIMDベースラインを前提としているため、実行時の検出や間接化の必要性を避け、代わりに積極的にインライン化を利用します。
ありがとうチャック –