乘法使用 SSE (x*x*x)+(y*y*y) [英] multiplication using SSE (x*x*x)+(y*y*y)

查看:64
本文介绍了乘法使用 SSE (x*x*x)+(y*y*y)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to optimize this function using SIMD but I don't know where to start.

long sum(int x,int y)
{
    return x*x*x+y*y*y;
}

反汇编后的函数如下所示:

The disassembled function looks like this:

  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)

调用代码如下所示:

 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);

推荐答案

  • 用 (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 会更有用..

    In the end, I'd actually be surprised if this turned out to be any faster than the simple code the compiler has already generated for you. SIMD is more useful if you have arrays of data you want to operate on..

    这篇关于乘法使用 SSE (x*x*x)+(y*y*y)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆