MOVDQUの特性について
IntelのOptimization Manualの2.2.5.1 Efficient Handling of Alignment Hazardsによると、Nehalem系CPUからMOVDQUの性能が向上したとあるので、実験してみました。
4パターンのmovを実行して速度差を見ます。alignedはアクセス先のアドレスが16バイトアライメントが取られているの意味、splitはアクセス先の領域(先頭+16バイト)がcache lineを跨ないの意味です。
- aligned MOVDQA
- aligned MOVDQU
- not-aligned split MOVDQU
- not-aligned not-split MOVDQU
実行環境はCore i5 2.66GHzと、Core2 Duo 1.6GHzです。続きにあるアセンブラ片を300000000回実行しています。
Core i5 | Core2 Duo | |
---|---|---|
aligned MOVDQA | 0.653 sec | 1.13 sec |
aligned MOVDQU | 0.633 sec | 2.26 sec |
not-aligned split MOVDQU | 2.802 sec | 14.947 sec |
not-aligned not-split MOVDQU | 0.636 sec | 2.26 sec |
確かにNehalem系CPUは、以前のCPUと比べてMOVDQUの性能が改善されています。cache lineを跨がなければMOVDQAと同じ速度が出ています。
aligned MOVDQA
asm volatile ( "movdqa (%0), %%xmm0;\n\t" "movdqa 16(%0), %%xmm1\n\t" "movdqa 32(%0), %%xmm2\n\t" "movdqa 48(%0), %%xmm3\n\t" "movdqa 64(%0), %%xmm4\n\t" "movdqa 80(%0), %%xmm5\n\t" : : "p" (data.data()) );
aligned MOVDQU
asm volatile ( "movdqu (%0), %%xmm0;\n\t" "movdqu 16(%0), %%xmm1\n\t" "movdqu 32(%0), %%xmm2\n\t" "movdqu 48(%0), %%xmm3\n\t" "movdqu 64(%0), %%xmm4\n\t" "movdqu 80(%0), %%xmm5\n\t" : : "p" (data.data()) );
not-aligned not-split MOVDQU
asm volatile ( "movdqu 1(%0), %%xmm0;\n\t" "movdqu 17(%0), %%xmm1\n\t" "movdqu 33(%0), %%xmm2\n\t" "movdqu 65(%0), %%xmm3\n\t" "movdqu 81(%0), %%xmm4\n\t" "movdqu 97(%0), %%xmm5\n\t" : : "p" (data.data()) );
not-aligned split MOVDQU
asm volatile ( "movdqu 63(%0), %%xmm0;\n\t" "movdqu 127(%0), %%xmm1\n\t" "movdqu 191(%0), %%xmm2\n\t" "movdqu 255(%0), %%xmm3\n\t" "movdqu 319(%0), %%xmm4\n\t" "movdqu 383(%0), %%xmm5\n\t" : : "p" (data.data()) );