gcc 自动矢量化控制循环中的流程
gcc auto vectorization control flow in loop
在下面的代码中,为什么第二个循环可以自动矢量化,而第一个循环不能?我如何修改代码以使其自动矢量化? gcc 说:
note: not vectorized: control flow in loop.
我使用的是 gcc 8.2,标志是 -O3 -fopt-info-vec-all。我正在为 x86-64 avx2 编译。
#include <stdlib.h>
#include <math.h>
void foo(const float * x, const float * y, const int * v, float * vec, float * novec, size_t size) {
size_t i;
float bar;
for (i=0 ; i<size ; ++i){
bar = x[i] - y[i];
novec[i] = v[i] ? bar : NAN;
}
for (i=0 ; i<size ; ++i){
bar = x[i];
vec[i] = v[i] ? bar : NAN;
}
}
更新:
这会自动向量化:
for (i=0 ; i<size ; ++i){
bar = x[i];
novec[i] = v[i] ? bar : NAN;
novec[i] -= y[i];
}
我仍然想知道为什么 gcc 说第一个循环的控制流。
clang 甚至会自动矢量化第一个循环,但 gcc8.2 不会。 (https://godbolt.org/z/cnlwuO)
gcc 使用 -ffast-math
向量化。也许它担心从减法中保留 FP 异常标志状态?
-fno-trapping-math
足以让 gcc 自动矢量化(没有 -ffast-math
设置的其余部分),所以显然它担心 FP 异常 。 (https://godbolt.org/z/804ykV)。我认为这是过于谨慎了,因为 C 源代码 确实 每次都计算 bar
,无论是否使用它。
gcc 将在没有任何 FP 数学选项的情况下自动矢量化简单的 FP a[i] = b[i]+c[i]
循环。
在下面的代码中,为什么第二个循环可以自动矢量化,而第一个循环不能?我如何修改代码以使其自动矢量化? gcc 说:
note: not vectorized: control flow in loop.
我使用的是 gcc 8.2,标志是 -O3 -fopt-info-vec-all。我正在为 x86-64 avx2 编译。
#include <stdlib.h>
#include <math.h>
void foo(const float * x, const float * y, const int * v, float * vec, float * novec, size_t size) {
size_t i;
float bar;
for (i=0 ; i<size ; ++i){
bar = x[i] - y[i];
novec[i] = v[i] ? bar : NAN;
}
for (i=0 ; i<size ; ++i){
bar = x[i];
vec[i] = v[i] ? bar : NAN;
}
}
更新: 这会自动向量化:
for (i=0 ; i<size ; ++i){
bar = x[i];
novec[i] = v[i] ? bar : NAN;
novec[i] -= y[i];
}
我仍然想知道为什么 gcc 说第一个循环的控制流。
clang 甚至会自动矢量化第一个循环,但 gcc8.2 不会。 (https://godbolt.org/z/cnlwuO)
gcc 使用 -ffast-math
向量化。也许它担心从减法中保留 FP 异常标志状态?
-fno-trapping-math
足以让 gcc 自动矢量化(没有 -ffast-math
设置的其余部分),所以显然它担心 FP 异常 。 (https://godbolt.org/z/804ykV)。我认为这是过于谨慎了,因为 C 源代码 确实 每次都计算 bar
,无论是否使用它。
gcc 将在没有任何 FP 数学选项的情况下自动矢量化简单的 FP a[i] = b[i]+c[i]
循环。