カテゴリ分けが難しい…
表題の通りだが、まぁいい。昨日は寝る前にSSEで遊んでみた(AthlonXPにはSSEまで実装)gccには浮動小数点演算をSSEに置き換えるコンパイルオプション-mfpmath=sseがあるので、cygwinでそのテスト。
次のソースを利用して、コンパイル結果と処理速度がどう変化するか実験。
int main(void){ int i,j; float f,g; for(j=0;j<10000;j++){ f = 5.35; g = 4.31; for(i=0;i<10000;i++){ f = f + g; } } return 0; }
まず、SSEを無効にして普通にコンパイルした結果(比較用に上のソースとはちょっと違ったものを使っています)
$ gcc -S sse1.c
movl $0x40ab3333, %eax movl %eax, -4(%ebp) movl $0x4089eb85, %eax movl %eax, -8(%ebp) flds -4(%ebp) fadds -8(%ebp) fstps -4(%ebp) movl $0, %eax
これをSSEを有効にし、浮動小数点演算を置き換えると次のようになる。
$ gcc -S -msse -mfpmath=sse sse1.c
movl $0x40ab3333, %eax movl %eax, -4(%ebp) movl $0x4089eb85, %eax movl %eax, -8(%ebp) movss -4(%ebp), %xmm0 addss -8(%ebp), %xmm0 movss %xmm0, -4(%ebp) movl $0, %eax
xmmレジスタを利用した演算となっているのがわかる。処理時間を比較してみよう。
SSE-OFF real 0m1.273s user 0m1.051s sys 0m0.040s
SSE-ON real 0m1.070s user 0m0.931s sys 0m0.020s
20%の高速化が認められる。
…あれ?アセンブラ的には命令数同じなんだけどな。ループ処理時のレジスタの扱い方に違いがあるのか、それともスーパスカラの効率が上がるのか…。なかなかおもしろい結果かと思います。
それにしても、コンパイルオプションを付けるだけでSSEを使ってくれるなんて楽しいな。VC6では考えられない処理だ。