使用SSE(x*x*x)+(y*y*y)进行乘法

she*_*rif 0 c x86 sse simd

我正在尝试使用SIMD优化此功能,但我不知道从哪里开始.

long sum(int x,int y)
{
    return x*x*x+y*y*y;
}
Run Code Online (Sandbox Code Playgroud)

反汇编函数如下所示:

  4007a0:   48 89 f2                mov    %rsi,%rdx
  4007a3:   48 89 f8                mov    %rdi,%rax
  4007a6:   48 0f af d6             imul   %rsi,%rdx
  4007aa:   48 0f af c7             imul   %rdi,%rax
  4007ae:   48 0f af d6             imul   %rsi,%rdx
  4007b2:   48 0f af c7             imul   %rdi,%rax
  4007b6:   48 8d 04 02             lea    (%rdx,%rax,1),%rax
  4007ba:   c3                      retq   
  4007bb:   0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
Run Code Online (Sandbox Code Playgroud)

调用代码如下所示:

 do {
for (i = 0; i < maxi; i++) {
  j = nextj[i];
  long sum = cubeSum(i,j);
  while (sum <= p) {
    long x = sum & (psize - 1);
    int flag = table[x];
    if (flag <= guard) {
      table[x] = guard+1;
    } else if (flag == guard+1) {
      table[x] = guard+2;
      count++;
    }
    j++;
    sum = cubeSum(i,j);
  }
  nextj[i] = j;
}
p += psize;
guard += 3;
} while (p <= n);
Run Code Online (Sandbox Code Playgroud)

jan*_*neb 6

  • 使用(x | y | 0 | 0)填充一个SSE寄存器(因为每个SSE寄存器包含4个32位元素).让我们称之为r1
  • 然后将该寄存器的副本复制到另一个寄存器r2
  • r2*r1,存储结果,比如说r2.
  • r2*r1再次将结果存储在r2中
  • 现在在r2你有(x*x*x | y*y*y | 0 | 0)
  • 将r2的下两个元素解压缩到单独的寄存器中,添加它们(SSE3有水平添加指令,但仅适用于浮点数和双精度数).

最后,如果结果比编译器为您生成的简单代码更快,我会感到惊讶.如果您要操作数据阵列,SIMD会更有用.