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;
}
追加命令だけを変更する必要があると思いますか?