次のループは、整数行列を別の整数行列に変換します。興味深いことにコンパイルすると、結果が出力マトリックスに格納されるmovaps
命令が生成されます。なぜgcc
ですか?このSSE2プログラム(整数)がなぜmovaps(浮動小数点数)を生成するのですか?
データ:
int __attribute__((aligned(16))) t[N][M]
, __attribute__((aligned(16))) c_tra[N][M];
ループ:
.L39:
lea rcx, [rsi+rdx]
movdqa xmm1, XMMWORD PTR [rdx]
add rdx, 16
add rax, 2048
movdqa xmm6, XMMWORD PTR [rcx+rdi]
movdqa xmm3, xmm1
movdqa xmm2, XMMWORD PTR [rcx+r9]
punpckldq xmm3, xmm6
movdqa xmm5, XMMWORD PTR [rcx+r10]
movdqa xmm4, xmm2
punpckhdq xmm1, xmm6
punpckldq xmm4, xmm5
punpckhdq xmm2, xmm5
movdqa xmm5, xmm3
punpckhqdq xmm3, xmm4
punpcklqdq xmm5, xmm4
movdqa xmm4, xmm1
punpckhqdq xmm1, xmm2
punpcklqdq xmm4, xmm2
movaps XMMWORD PTR [rax-2048], xmm5
movaps XMMWORD PTR [rax-1536], xmm3
movaps XMMWORD PTR [rax-1024], xmm4
movaps XMMWORD PTR [rax-512], xmm1
cmp r11, rdx
jne .L39
gcc -Wall -msse4.2 -masm="intel" -O2 -c -S
skylake
linuxmint
for(i=0; i<N; i+=4){
for(j=0; j<M; j+=4){
row0 = _mm_load_si128((__m128i *)&t[i][j]);
row1 = _mm_load_si128((__m128i *)&t[i+1][j]);
row2 = _mm_load_si128((__m128i *)&t[i+2][j]);
row3 = _mm_load_si128((__m128i *)&t[i+3][j]);
__t0 = _mm_unpacklo_epi32(row0, row1);
__t1 = _mm_unpacklo_epi32(row2, row3);
__t2 = _mm_unpackhi_epi32(row0, row1);
__t3 = _mm_unpackhi_epi32(row2, row3);
/* values back into I[0-3] */
row0 = _mm_unpacklo_epi64(__t0, __t1);
row1 = _mm_unpackhi_epi64(__t0, __t1);
row2 = _mm_unpacklo_epi64(__t2, __t3);
row3 = _mm_unpackhi_epi64(__t2, __t3);
_mm_store_si128((__m128i *)&c_tra[j][i], row0);
_mm_store_si128((__m128i *)&c_tra[j+1][i], row1);
_mm_store_si128((__m128i *)&c_tra[j+2][i], row2);
_mm_store_si128((__m128i *)&c_tra[j+3][i], row3);
}
}
アセンブリコードを生成しました
-mavx2
または-march=naticve
は、VEXエンコーディング:vmovaps
を生成します。
実際にIntelとAMDが推奨するコード生成の練習です。実際のところ、最新のCPUの場合、アライメントされた/整列されていないロードでは、パフォーマンスに合わせた書き込みが同じであるため、常に「 '' movups''を使うことをお勧めします。 [Intel](http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-optimization-manual.html)および[AMD](http: //developer.amd.com/resources/developer-guides-manuals/)ソフトウェア最適化ガイド –
@ChuckWalbourn 'movups'と' movaps'はNehalem以来同じ性能しか持っていません。しかし、 'movups'が操作を折り畳むことができないので、本当に' vmovaps'だけが時代遅れです。 IntelとAMDの推奨事項は確実ですか?あなたのハードウェアがそれをサポートしているならば、常に 'vmovups'を使うことを意味します。 –
@ChuckWalbournあなたが指摘したインテルマニュアルを検索しましたが、あなたが言及した推奨事項が見つかりませんでした。どのセクションを参照していますか。私も 'vmovaps'を探していました。コードで何度か表示されていますので、Intelもそれを使っています。 –