私はIvy-Bridge CPUを持っています。 次のコードは、反復ごとに3サイクルかかり、次2つの同様のアセンブリコード。実質的な差
L1:
movapd xmm1, [rsi+rax] ; X[i], X[i+1]
mulpd xmm1, xmm2
movapd xmm0, [rdi+rax] ; Y[i], Y[i+1]
subpd xmm0, xmm1
movapd [rdi+rax], xmm0 ; Store result
add rax, 16
cmp rax, rcx
jl L1
を反復ごとに9サイクルを要する:
L1:
movapd xmm1, [rsi+rax] ; X[i], X[i+1]
mulpd xmm1, xmm2
movapd xmm0, [rdi+rax] ; Y[i], Y[i+1]
add rax, 16
subpd xmm0, xmm1
movapd [rdi+rax], xmm0 ; Store result
cmp rax, rcx
jl L1
唯一の違いは順序(add rax, 16
)です。そしてそれはプログラムが3倍遅くなることを引き起こします。なぜその違いが非常に大きいのですか?
は「あなたが戻って同じ場所に格納するストア命令を変更した場合、私は想像、第二のループは、実質的に速く再びなる:」 あなたは正しいです! :) 私の質問は: なぜ 'add rax、16'は遅くなりませんか?結局のところ、 'movapd [rdi + rax-16]、xmm0'は' rax'の値を変更するので、 'add rax、16'の後に依存関係があります。たぶん登録Renamingはここで役割を果たしますか? – Gilgamesz
さて、整数加算のレイテンシはかなり小さいです(1サイクル)?さらに重要なのは、ループのネット反復でxmm命令を使用することに依存しないため、ストアがまだ保留中の間にすべて開始できることです。遅い場合の減速を引き起こす命令との干渉。 –