развернуть вложенные для циклов в C ++ - PullRequest
0 голосов
/ 01 мая 2010

Как бы я развернул следующие вложенные циклы?

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

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

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

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

Ответы [ 2 ]

2 голосов
/ 01 мая 2010
   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)

1 голос
/ 01 мая 2010

Я думаю, что 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;
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...