以下循环将整数矩阵转置为另一个整数矩阵。当我编译有趣的时候,它会生成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',并在代码中显示了几次,所以即使英特尔仍在使用它。 –