以下循環將整數矩陣轉置爲另一個整數矩陣。當我編譯有趣的時候,它會生成movaps
指令將結果存儲到輸出矩陣中。爲什麼gcc
這樣做?爲什麼這個SSE2程序(整數)產生movaps(float)?
數據:
int __attribute__((aligned(16))) t[N][M]
, __attribute__((aligned(16))) c_tra[N][M];
循環:
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);
}
}
大會生成的代碼:
.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
-mavx2
或-march=naticve
生成VEX編碼:vmovaps
。
這實際上是英特爾和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自從Nehalem以來,'movups'和'movaps'只有相同的表現。但即使這是誤導性的,因爲'movups'不能摺疊操作,因此只有'vmovaps'已經過時。那麼你確定這是英特爾和AMD的建議嗎?如果你的硬件支持它,它們可能意味着總是使用'vmovups'。 –
@ChuckWalbourn我搜索了您指向的英特爾手冊,但沒有找到您提到的建議。你指的是哪一部分。我還搜索了'vmovaps',並在代碼中顯示了幾次,所以即使英特爾仍在使用它。 –