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())
        );