c - 数学 'pow' 函数 gcc 的 SSE 矢量化

标签 c optimization loops sse vectorization

我试图向量化一个循环,该循环包含数学库中“pow”函数的使用。我知道英特尔编译器支持对 sse 指令使用“pow”——但我似乎无法让它与 gcc 一起运行(我认为)。这是我正在处理的情况:

int main(){
        int i=0;
        float a[256],
        b[256];

        float x= 2.3;


        for  (i =0 ; i<256; i++){
                a[i]=1.5;
        }

        for (i=0; i<256; i++){
                b[i]=pow(a[i],x);
        }

        for (i=0; i<256; i++){
                b[i]=a[i]*a[i];
        }
    return 0;

}

我正在编译以下内容:

gcc -O3 -Wall -ftree-vectorize -msse2 -ftree-vectorizer-verbose=5 code.c -o runthis

这是在 os X 10.5.8 上使用 gcc 4.2 版(我也使用 4.5 并且无法判断它是否矢量化了任何东西 - 因为它根本没有输出任何东西)。似乎没有一个循环矢量化 - 是否存在对齐问题或我需要使用限制的其他问题?如果我将其中一个循环写成一个函数,我会得到稍微更冗长的输出(代码):

void pow2(float *a, float * b, int n) {
        int i;
        for (i=0; i<n; i++){
                b[i]=a[i]*a[i];
        }
}

输出(使用 7 级详细输出):

note: not vectorized: can't determine dependence between *D.2878_13 and *D.2877_8
bad data dependence.

我查看了 gcc auto-vectorization页,但这并没有多大帮助。如果无法在 gcc 版本中使用 pow,我在哪里可以找到执行 pow 等效函数的资源(我主要处理整数幂)。

编辑 所以我只是在挖掘其他来源 - 它是如何矢量化这个的?!:

void array_op(double * d,int len,double value,void (*f)(double*,double*) ) { 
    for ( int i = 0; i < len; i++ ){
        f(&d[i],&value);
    }
};

相关的 gcc 输出:

note: Profitability threshold is 3 loop iterations.

note: LOOP VECTORIZED.

现在我不知所措 -- 'd' 和 'value' 被 gcc 不知道的函数修改了 - 奇怪吗?也许我需要更彻底地测试这部分,以确保矢量化部分的结果是正确的。仍在寻找矢量化数学库 - 为什么没有开源库?

最佳答案

在写入输出之前使用 __restrict 或消耗输入(分配给本地变量)应该会有所帮助。

现在,编译器无法向量化,因为 a 可能是 b 的别名,因此并行执行 4 次乘法并写回 4 个值可能不正确。

(请注意,__restrict 不能保证编译器矢量化,但现在可以说这么多,它肯定不能)。

关于c - 数学 'pow' 函数 gcc 的 SSE 矢量化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6918141/

相关文章:

检查 C 字符串中的某些字符

c - freeDiameter - 事件时间戳

c++ - 整数除法,还是 float 乘法?

javascript - 为什么我的获取对象属性值的循环不起作用?

php - 我想按照以下条件应用 css 类

python - 将簇分配给对象中的每个壳 - Maya Python

c - 链接到另一个共享对象的共享对象

c - 为什么数组变量不能指向其他地方?

XSLT 的优化

c# - 删除 foreach - C# 代码优化