2009/08/08
Direct3D Matrix の並びと SSE 命令 (2)
先日の SSE 命令の実行速度を試してみました。
あまり厳密なものではなくて、掲載したコード 3種類をそのままループで回しただけです。
単位は時間で値が小さい方が高速です。
Core2 実行時、SSE3 hadd で遅くなってしまい少々焦りました。
昨日これで良いって書いたばかりなのに。結局元のコードの方が速いという結果に。
Core i7 の場合は正反対で hadd が最速になっています。
おかしなことに x64 のみ SSE1 で極端に速度が落ちています。
実際に x64+SSE1 の展開されたコードを見てみると、x64 で増えたレジスタを最大限
使おうとしてループの先頭で全部レジスタにロードしていました。
その分転送などの命令が他のケースよりも増えています。
このテストは局所的な小さいループかつ、使用したデータもストリーム入出力ではなく
同じ領域へのたたみ込みでした。
それゆえすべてのデータがキャッシュに乗った状態だと考えられます。
レジスタ間の転送命令が増えるよりもおそらくキャッシュに乗ったメモリから
読み直した方が速いのでしょう。
実際に SSE 命令が使われるケースだとストリーム処理が多いため、必ずしも
このような結果にはならないと思われます。
haddps , dpps の実行性能は CPU によって逆転することがわかりました。
この両者は比較的似たようなコードに展開されています。
ループ内の命令数も同数でした。
プロセッサによって異なるため、やはり指針としては命令数を減らすことを考えて
書くのが良さそうです。
関数は intrinsics 命令で記述しためコンパイラは inline 展開しており、
複数の関数に渡って並べ替えなどの最適化が行われています。
intrinsic 命令がどのように展開されるかだけ把握しておけば asm を使わない方が
良いかもしれません。x64 だと使えないし。
_mm_setr_ps とかは結構命令数食います。
関連エントリ
・Direct3D Matrix の並びと SSE 命令
・Intel AVX その3 命令
・D3D10 row_major column_major
・SSE についてのメモ(2) SSE4など
あまり厳密なものではなくて、掲載したコード 3種類をそのままループで回しただけです。
● Core2 Duo P8600 2.4GHz Windows7 x86 x86 SSE1 17581 (msec) mulps+addps x86 SSE3 20623 haddps x86 SSE4.1 17799 dpps ● Core i7 940 2.93GHz Windows7 RC x64 x86 SSE1 14320 mulps+addps x86 SSE3 11716 haddps x86 SSE4.1 13682 dpps x64 SSE1 17269 mulps+addps x64 SSE3 11076 haddps x64 SSE4.1 13681 dpps
単位は時間で値が小さい方が高速です。
Core2 実行時、SSE3 hadd で遅くなってしまい少々焦りました。
昨日これで良いって書いたばかりなのに。結局元のコードの方が速いという結果に。
Core i7 の場合は正反対で hadd が最速になっています。
おかしなことに x64 のみ SSE1 で極端に速度が落ちています。
実際に x64+SSE1 の展開されたコードを見てみると、x64 で増えたレジスタを最大限
使おうとしてループの先頭で全部レジスタにロードしていました。
その分転送などの命令が他のケースよりも増えています。
このテストは局所的な小さいループかつ、使用したデータもストリーム入出力ではなく
同じ領域へのたたみ込みでした。
それゆえすべてのデータがキャッシュに乗った状態だと考えられます。
レジスタ間の転送命令が増えるよりもおそらくキャッシュに乗ったメモリから
読み直した方が速いのでしょう。
実際に SSE 命令が使われるケースだとストリーム処理が多いため、必ずしも
このような結果にはならないと思われます。
haddps , dpps の実行性能は CPU によって逆転することがわかりました。
この両者は比較的似たようなコードに展開されています。
ループ内の命令数も同数でした。
プロセッサによって異なるため、やはり指針としては命令数を減らすことを考えて
書くのが良さそうです。
関数は intrinsics 命令で記述しためコンパイラは inline 展開しており、
複数の関数に渡って並べ替えなどの最適化が行われています。
intrinsic 命令がどのように展開されるかだけ把握しておけば asm を使わない方が
良いかもしれません。x64 だと使えないし。
_mm_setr_ps とかは結構命令数食います。
関連エントリ
・Direct3D Matrix の並びと SSE 命令
・Intel AVX その3 命令
・D3D10 row_major column_major
・SSE についてのメモ(2) SSE4など