相关疑难解决方法(0)

为什么GCC不优化a*a*a*a*a*a到(a*a*a)*(a*a*a)?

我正在对科学应用进行一些数值优化.我注意到的一件事是GCC会pow(a,2)通过编译来优化调用a*a,但调用pow(a,6)没有优化,实际上会调用库函数pow,这会大大降低性能.(相比之下,英特尔C++编译器,可执行文件icc,将消除库调用pow(a,6).)

我很好奇的是,当我更换pow(a,6)a*a*a*a*a*a使用GCC 4.5.1和选项" -O3 -lm -funroll-loops -msse4",它采用5分mulsd的说明:

movapd  %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
Run Code Online (Sandbox Code Playgroud)

如果我写(a*a*a)*(a*a*a),它会产生

movapd  %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm13, %xmm13
Run Code Online (Sandbox Code Playgroud)

这将乘法指令的数量减少到3. icc具有类似的行为.

为什么编译器不能识别这种优化技巧?

floating-point assembly gcc compiler-optimization fast-math

2083
推荐指数
12
解决办法
20万
查看次数

自动矢量化不起作用

我正在尝试将我的代码设置为自动向量化,但它无法正常工作.

int _tmain(int argc, _TCHAR* argv[])
{
    const int N = 4096;
    float x[N];
    float y[N];
    float sum = 0;

    //create random values for x and y 
    for (int i = 0; i < N; i++)
    {
        x[i] = rand() >> 1;
        y[i] = rand() >> 1;
    }

    for (int i = 0; i < N; i++){
        sum += x[i] * y[i];
    }
}
Run Code Online (Sandbox Code Playgroud)

这里没有循环矢量化,但我真的只对第二个循环感兴趣.

我正在使用visual studio express 2013并且正在编译/O2/Qvec-report:2(报告循环是否被矢量化)选项.编译时,我收到以下消息:

--- Analyzing function: main
c:\users\...\documents\visual studio 2013\projects\intrin3\intrin3\intrin3.cpp(28) …
Run Code Online (Sandbox Code Playgroud)

c++ optimization sse simd vectorization

7
推荐指数
1
解决办法
2439
查看次数