我正在尝试使用 SSE 和 SSE3 编写一个简单的代码来计算数组所有元素的总和。不同之处在于,在其中一个代码中,我使用 PADDD“垂直”求和,而在另一个代码中,我使用 HADPPS 水平求和。由于我感兴趣的唯一值是总和,所以我计算总和的方式应该无关紧要。但是,水平加法会输出错误的结果。知道为什么吗?
这是常规添加的代码:
int sumelems_sse(int *a, int size)
{
int tmp[4];
tmp[0] = 0;
tmp[1] = 0;
tmp[2] = 0;
tmp[3] = 0;
int total;
__asm__ volatile (
"\n\t movdqa %0,%%xmm0 \t#" // moves tmp[0] to xmm0
: /* no output */
: "m" (tmp[0]) //%0
);
for (int i=0;i<size;i+=4) {
__asm__ volatile
( // instruction comment
"\n\t movdqa %0,%%xmm1 \t#" // moves a[i] to xmm1
"\n\t paddd %%xmm1,%%xmm0 \t#" // xmm0 = xmm0+xmm1 in 4 blocks of 32 bits
: /* no output */
: "m" (a[i]) // %0
);
}
__asm__ volatile(
"\n\t movdqa %%xmm0,%0 \t#" // moves xmm0 to tmp[0]
: "=m" (tmp[0])
);
total = tmp[0] + tmp[1] + tmp[2] + tmp[3];
return total;
}
这是水平添加的代码:
int sumelems_sse3(int *a, int size)
{
int tmp[4];
tmp[0] = 0;
tmp[1] = 0;
tmp[2] = 0;
tmp[3] = 0;
int total;
__asm__ volatile (
"\n\t movdqa %0,%%xmm0 \t#" // moves tmp[0] to xmm0
: /* no output */
: "m" (tmp[0]) //%0
);
for (int i=0;i<size;i+=4) {
__asm__ volatile
( // instruction comment
"\n\t movdqa %0,%%xmm1 \t#" // moves a[i] to xmm1
"\n\t haddps %%xmm1,%%xmm0 \t#" // xmm0 = xmm0+xmm2 in 4 blocks of 32 bits
: /* no output */
: "m" (a[i]) // %0
);
}
__asm__ volatile(
"\n\t movdqa %%xmm0,%0 \t#" // moves xmm0 to tmp[0]
: "=m" (tmp[0])
);
total = tmp[0] + tmp[1] + tmp[2] + tmp[3];
return total;
}
我认为只有添加指令应该改变,还是不改变?