如何使GCC向量化此循环

how to enable gcc to vectorize this loop

本文关键字:循环 向量化 GCC 何使      更新时间:2023-10-16

我有这个循环,其中b2float, x1float的(特征c++)向量,a1a0int

for(int i=1;i<9;i++)
    b2+=a0*(float)0.5*(std::log(fabs(x1(a1+a0*(i-1))))+std::log(fabs(x1(a1+a0*i))));

GCC的回报:

analyze_innermost: failed: evolution of base is not affine.

我想知道是否有一个简单的方法来重写循环,以允许GCC向量化它(我正在编译与所有不安全的选项启用…我这样做是为了学习)。

<标题>编辑:

x1是一个特征构造。

我会把它分成3个循环:

float t1[9];
float t2[9];
for (i = 0; i < 9; ++i)                // (1) - gather input terms
    t1[i] = x1(a1+a0*i);
for (i = 0; i < 9; ++i)                // (2) - do expensive log/fabs operations
    t2[i] = std::log(fabs(t1[i]));     //       with minimum redundancy
for (i = 1; i < 9; ++i)                // (3) - wrap it all up
    b2 += a0*0.5f*(t2[i-1] + t2[i]);

我怀疑(1)可能不是矢量化的(除非您有AVX2和聚集负载),但是(2)和(3)有合理的机会。

您的示例不能容易地向量化,因为您没有以顺序方式访问x1的条目。

对于顺序访问,它可以像这样向量化:
ArrayXf x1;
b2 = (x1.segment(i,9).abs().log() + x1.segment(j,9).abs().log()).sum() * a0;