如何启用gcc来矢量化这个循环

时间:2014-03-21 12:33:47

标签: c++ gcc vectorization eigen

我有这个循环,其中b2floatx1floata1和{{1}的(Eigen c ++)向量是a0

int

海湾合作委员会回归:

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对其进行矢量化(我正在编译所有启用的不安全选项......我正在这样做以学习)。

编辑:

x1是特征构造。我正在使用带有O3标志的GCC 4.8.1。

2 个答案:

答案 0 :(得分:1)

您的示例无法轻松进行矢量化,因为您没有按顺序访问x1的条目。

通过顺序访问,它可以像这样进行矢量化:

ArrayXf x1;
b2 = (x1.segment(i,9).abs().log() + x1.segment(j,9).abs().log()).sum() * a0;

答案 1 :(得分:1)

我会将其分解为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)有合理的机会。