Reputation: 5789
I have this loop where b2
is a float
, x1
is a (Eigen c++) vector of float
, a1
and a0
are 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 returns:
analyze_innermost: failed: evolution of base is not affine.
I was wondering if there was a simple way to rewrite the loop to allow GCC to vectorize it (I'm compiling with all the unsafe options enabled...I'm doing this to learn).
x1 is an eigen construct. I'm using GCC 4.8.1 with O3 flag.
Upvotes: 1
Views: 912
Reputation: 212959
I would break this up into 3 loops:
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]);
I suspect that (1) may not be vectorizable (unless you have AVX2 with gathered loads), but (2) and (3) have a reasonable chance.
Upvotes: 1
Reputation: 29205
Your example cannot be easily vectorized because you're not accessing the entries of x1 in a sequential manner.
With sequential access, it could be vectorized like that:
ArrayXf x1;
b2 = (x1.segment(i,9).abs().log() + x1.segment(j,9).abs().log()).sum() * a0;
Upvotes: 1