0

我正在尝试使用 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;

}

我认为只有添加指令应该改变,还是不改变?

4

0 回答 0