jap*_*iss 7 c++ assembly code-generation pipelining visual-studio-2012
我从以下SIMD代码中检出了Visual Studio 2012的程序集输出:
float *end = arr + sz;
float *b = other.arr;
for (float *a = arr; a < end; a += 4, b += 4)
{
__m128 ax = _mm_load_ps(a);
__m128 bx = _mm_load_ps(b);
ax = _mm_add_ps(ax, bx);
_mm_store_ps(a, ax);
}
Run Code Online (Sandbox Code Playgroud)
循环体是:
$LL11@main:
movaps xmm1, XMMWORD PTR [eax+ecx]
addps xmm1, XMMWORD PTR [ecx]
add ecx, 16 ; 00000010H
movaps XMMWORD PTR [ecx-16], xmm1
cmp ecx, edx
jb SHORT $LL11@main
Run Code Online (Sandbox Code Playgroud)
为什么增加ecx
16,只有当存储到下一行时减去16?
嗯,这里基本上有两种选择.
add ecx, 16
movaps XMMWORD PTR [ecx-16], xmm1 ; stall for ecx?
cmp ecx, edx
jb loop
Run Code Online (Sandbox Code Playgroud)
要么
movaps XMMWORD PTR [ecx], xmm1
add ecx, 16
cmp ecx, edx ; stall for ecx?
jb loop
Run Code Online (Sandbox Code Playgroud)
在选项1中,你add
和之间有一个潜在的失速movaps
.在选项2中,你add
和之间有一个潜在的失速cmp
.但是,还存在使用执行单元的问题.add
和cmp
(= sub
)使用ALU,而我[ecx-16]
使用AGU(地址生成单元),我相信.因此我怀疑选项1中可能会略微获胜,因为ALU使用与AGU使用交错.