我试图向量化一个循环,该循环包含数学库中“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/