カテゴリ分けが難しい…

表題の通りだが、まぁいい。昨日は寝る前に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では考えられない処理だ。