2010-05-01 2 views
-1

Как мне развернуть следующие вложенные циклы?unroll вложенные для циклов в C++

for(k = begin; k != end; ++k) { 
for(j = 0; j < Emax; ++j) { 
    for(i = 0; i < N; ++i) { 
    if (j >= E[i]) continue; 
    array[k] += foo(i, tr[k][i], ex[j][i]); 
    } 
} 
} 

Я попытался следующие, но мой выход не то же самое, и это должно быть:

for(k = begin; k != end; ++k) { 
for(j = 0; j < Emax; ++j) { 
    for(i = 0; i+4 < N; i+=4) { 
    if (j >= E[i]) continue; 
    array[k] += foo(i, tr[k][i], ex[j][i]); 
    array[k] += foo(i+1, tr[k][i+1], ex[j][i+1]); 
    array[k] += foo(i+2, tr[k][i+2], ex[j][i+2]); 
    array[k] += foo(i+3, tr[k][i+3], ex[j][i+3]); 
    } 
    if (i < N) { 
    for (; i < N; ++i) { 
    if (j >= E[i]) continue; 
    array[k] += foo(i, tr[k][i], ex[j][i]); 
    } 
    } 
} 
} 

Я будет работать этот код в параллельном режиме с использованием TBB Intel, так что он использует несколько ядер. По завершении работы другая функция выдает то, что находится в массиве [], и прямо сейчас, при моей разворачивании, вывод не идентичен. Любая помощь приветствуется.

Обновление: я исправил его. Я использовал ответ для этого вопроса, чтобы сделать разворот ... результат не был сопоставлен, потому что я не делал array[k] = 0; после первого цикла for.

Спасибо, Христо

+0

Это вопрос С. –

+0

@ VicenteBotetEscriba - это может быть C или C++ ... зависит от того, как он скомпилирован. –

+0

Это C++, а не C – Hristo

ответ

2
if (j >= E[i]) continue; 
    array[k] += foo(i, tr[k][i], ex[j][i]); 
    array[k] += foo(i+1, tr[k][i+1], ex[j][i+1]); 
    array[k] += foo(i+2, tr[k][i+2], ex[j][i+2]); 
    array[k] += foo(i+3, tr[k][i+3], ex[j][i+3]); 

против

if (j >= E[i]) continue; 
array[k] += foo(i, tr[k][i], ex[j][i]); 

условия скрининга не являются идентичными

лучший подход к скрининга (устранение ветвления):

array[k] += (j < E[i])*foo(i, tr[k][i], ex[j][i]); 

также, вы должны гарантировать, что N делится на 4, иначе вы можете перерегулировать. в качестве альтернативы, усекать N, чтобы делиться на четыре (N - N% 4)

+0

Вот почему я добавил if (i Hristo

+0

@hri okay, я этого не видел. чем, скорее всего, это только условие скрининга. – Anycorn

+0

вы делаете хороший момент. Я добавил «if (j> = E [i + 1])» для каждого из 4 вызовов foo (я тоже сделал +2 и +3), но это, похоже, не исправить:/ – Hristo

1

Я думаю, что ваша проблема связана с if (j >= E[i]) continue;. В оригинале этот тест запускается для каждого индекса i. В вашей развернутой версии он проверяется только на каждый четвертый индекс. Попробуйте следующее:

for (i = 0; i < N; /*advanced in loop*/) { 
    if (j >= E[i]) continue; 
    array[k] += foo(i, tr[k][i], ex[j][i]); ++i; 
    if (j >= E[i]) continue; 
    array[k] += foo(i, tr[k][i], ex[j][i]); ++i; 
    if (j >= E[i]) continue; 
    array[k] += foo(i, tr[k][i], ex[j][i]); ++i; 
    if (j >= E[i]) continue; 
    array[k] += foo(i, tr[k][i], ex[j][i]); ++i; 
} 
while (i < N) { 
    if (j >= E[i]) { 
     ++i; // missing in original version 
     continue; 
    } 
    array[k] += foo(i, tr[k][i], ex[j][i]); 
    ++i; 
} 

Edit: Я забыл, чтобы увеличить индекс в оригинальной версии, которая вызывает бесконечный цикл, когда j >= E[i].

+0

Хмм ... Это имеет смысл. Однако он все еще не работает. Я не знаю, почему. Когда цикл while в конце, кажется, застрял в бесконечном цикле. Но если я использую цикл for, как указано выше, вывод неверен. – Hristo

+1

что если 'if (j> = E [i]) continue' всегда верно? вы получаете бесконечный цикл – Anycorn

+0

Продолжение проскакивает слишком далеко. Попробуйте, если (j Accipitridae

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