x86命令の所要クロック計測スレ

このエントリーをはてなブックマークに追加
2181
では、いよいよ組み込み関数を使う。"emmintrin.h"をインクルード。
for (i=0; i<1000; i+=2) s=_mm_add_pd (s, _mm_loadu_pd( &p[i]));
アライメントが合ってない状態でmovapdしてたのに気づかず長時間悩んだ。Cだと油断する。
$L1941:
movupd xmm1, XMMWORD PTR [eax]
add eax, 16
dec ecx
addpd xmm0, xmm1
jne SHORT $L1941

2300clkだった。変数のsはqとrをくっつけたもので、addpdはfaddを2回やっている。
実行ユニット的にはに上の2000clkのコードと同じなのだ。
で、更に並列性を上げる。
for (i=0; i<1000; i+=4){ s=_mm_add_pd (s, _mm_loadu_pd( &p[i])); t=_mm_add_pd (t, _mm_loadu_pd( &p[i+2])); }
$L1975:
movapd xmm1, XMMWORD PTR _t$[esp+8064]
npad 9 ;この9byte nop って意味あるのか?
$L1943: ;ここへジャンプしてループに入る。
movupd xmm2, XMMWORD PTR [eax-16]
addpd xmm0, xmm2
movupd xmm2, XMMWORD PTR [eax]
add eax, 32
dec ecx
addpd xmm1, xmm2
movapd XMMWORD PTR _t$[esp+8064], xmm1
jne SHORT $L1975

これが2400clk程度。遅い。どう考えてもmovapdが無駄なのだが。
直前にこれを書いた。
s=_mm_xor_pd (s, s); t=_mm_xor_pd (t, t);
このtの部分をt=s; としたら無駄なmovapdはなくなり、1900clkになった。
更にもう1回アンロールで1700clk。意外と伸びない。