【问题标题】:gcc auto vectorization control flow in loop循环中的 gcc 自动矢量化控制流程
【发布时间】:2019-04-12 01:25:17
【问题描述】:

在下面的代码中,为什么第二个循环可以自动矢量化,而第一个不能?如何修改代码使其自动矢量化? gcc 说:

注意:未矢量化:循环中的控制流。

我使用的是 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 说第一个循环的控制流。

【问题讨论】:

  • 为我矢量化。
  • @EOF:clang 按照您期望的方式对其进行矢量化,但 gcc8.2 没有。 (即使将restrict 添加到所有指针,并使用-march=haswellgodbolt.org/z/cnlwuO

标签: c gcc avx2 auto-vectorization


【解决方案1】:

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 a[i] = b[i]+c[i] 循环,而无需任何 FP 数学选项。

【讨论】:

  • (GCC 的默认值 -ftrapping-math 在另一种情况下也是错误的:有时它计算 C 源不计算的东西,可能会引发源不会的 FP 异常'没有。所以它只是坏了,并且已经存在很长时间了。我建议将-fno-trapping-math 作为标准选项的一部分,以及-fno-math-errno-O3 -march=native。)
猜你喜欢
  • 2011-12-29
  • 2019-04-05
  • 2018-12-16
  • 2011-06-28
  • 1970-01-01
  • 2019-01-09
  • 1970-01-01
  • 2016-06-03
  • 1970-01-01
相关资源
最近更新 更多