我有这个循环,其中b2
是float
,x1
是float
,a1
和{{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。
答案 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)有合理的机会。