适用于x86的GCC:优化两对浮点数之和

时间:2019-12-19 17:20:51

标签: gcc simd avx avx2

我正在通过优化对下面的代码进行编译,并且看起来仍然存在使用底层硬件的SIMD功能执行这两个求和的更有效方法。对于GCC生成会成对加载操作数并在一条指令中执行两个加法的程序集的标志,正确的标志混合方式是什么?

#include <iostream>

struct foo {
    float val[2];

    foo(float a, float b)
    {
        val[0] = a;
        val[1] = b;
    }

    foo& operator+=(
            const foo &rhs)
    {
        val[0] += rhs.val[0];
        val[1] += rhs.val[1];
        return *this;
    }
};


int main(void)
{
    volatile float values[] = { 2.0, 3.0, 4.0, 7.0 };
    foo first(values[0], values[1]);
    foo second(values[2], values[3]);

    second += first;

    std::cout << "(" << second.val[0] << ","
            << second.val[1] << ")" << std::endl;

    return 1;
}

生成的汇编代码看起来像这样(仅对于operator +()而言),似乎很明显所有操作数都被单独对待。

  400712:   c5 fa 10 4c 24 14       vmovss 0x14(%rsp),%xmm1
  400718:   c5 fa 10 5c 24 10       vmovss 0x10(%rsp),%xmm3
    foo second(values[2], values[3]);
  40071e:   c5 fa 10 44 24 1c       vmovss 0x1c(%rsp),%xmm0
  400724:   c5 fa 10 54 24 18       vmovss 0x18(%rsp),%xmm2
        val[1] += rhs.val[1];
  40072a:   c5 f2 58 e8             vaddss %xmm0,%xmm1,%xmm5
        val[0] += rhs.val[0];
  40072e:   c5 e2 58 e2             vaddss %xmm2,%xmm3,%xmm4
        val[1] += rhs.val[1];
  400732:   c5 fa 11 6c 24 0c       vmovss %xmm5,0xc(%rsp)
        val[0] += rhs.val[0];
  400738:   c5 fa 11 64 24 08       vmovss %xmm4,0x8(%rsp)

我使用此命令进行编译(但是删除-mavx2不会对结果产生太大影响):

g++ -O3 -mavx2 -g -std=c++11 main.cpp -o run

万一重要,那就是GCC 6.3(并且实际上没有升级的自由)。

0 个答案:

没有答案