2014-03-21 5 views
1

У меня есть этот цикл, где b2 является float, x1 является вектором float, a1 и a0 являются int а (Эйген C++).как включить GCC векторизовать эту петлю

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)))); 

ССАГПЗ возвращается:

analyze_innermost: failed: evolution of base is not affine. 

Я задавался вопросом, есть ли простой способ переписать цикл, чтобы GCC векторизовать его (я компиляции со всеми включенными опциями небезопасных ... Я делаю это, чтобы учиться).

Редактировать:

x1 - собственная конструкция. Я использую GCC 4.8.1 с флагом O3.

+1

Является ли 'x1' стандартным (STL) вектором? Вы перегрузили 'operator()' или что-то еще? –

+0

Вы пытались хранить RHS оператора '+ =' во временном массиве и использовать второй цикл, чтобы суммировать их? – anderas

+0

@OMGtechy Не дублируется. Ошибка и код совершенно разные –

ответ

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) имеют разумные шансы.

+1

спасибо за это: он получил вектор (как вы и предсказывали), и это помогло мне понять, как это работает. Я потратил конец недели, указав все узкие места в этом коде, и они работают в 3+ раза быстрее! – user189035

+0

@ user189035: отлично - спасибо за продолжение этого и дайте сообществу понять, что он эффективен - это полезная информация. –

1

Ваш пример не может быть легко векторизован, потому что вы не получаете доступа к элементам x1 последовательным образом.

с последовательным доступом, он может быть векторизованы так:

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

Спасибо. К сожалению, я не вижу возможности доступа к элементам x1 последовательно, за исключением предварительной выборки, хранения их в векторе длиной 8 и суммировании этого вектора. – user189035

Смежные вопросы