矢量化平方残差与gcc / clang之和无内在函数

时间:2014-02-26 09:28:49

标签: c performance sse avx

我试图说服gcc(4.8.1)或clang(3.4)来对以下内容进行矢量化 常春藤网桥处理器上的代码:

#include "stdlib.h"
#include "math.h"

float sumsqr(float *v, float mean, size_t n) {
    float ret = 0;
    for(size_t i = 0; i < n; i++) {
        ret += pow((v[i] - mean), 2);
    }
    return ret;
}

并且没有成功编译

$ gcc -std=c99 -O3 -march=native -mtune=native -ffast-math -S foo.c

有没有办法修改代码而不使用instrinsics或修改gcc调用以获得矢量化代码?

2 个答案:

答案 0 :(得分:8)

pow函数非常通用,编译器可能看不到它的作用(请记住它可以计算像pow(1.8, -3.19)这样的东西。所以它可能只能用于内置操作,并且不进行函数调用:

for(size_t i = 0; i < n; i++)
{
    float const x = v[i] - mean;
    ret += x * x;
}

答案 1 :(得分:1)

首先,如果你不必,不要使用pow,简单的乘法让gcc矢量化。现在解释为什么会出现这种行为,请注意用pow替换powf,gcc设法进行向量化。 gcc知道pow(x,2)x*x,但问题是powdouble的函数。因此编译器必须将数字v[i]-mean转换为double,将square计算为double,将其作为double添加到ret,然后才转换为float。如果至少ret是一个double,那么编译器可以进行矢量化,但是所有这些转换都会使它太复杂而且不值得向量化。