簡體   English   中英

在C ++中展開嵌套嵌套循環

[英]unroll nested for loops in 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並行運行此代碼,以便利用多核。 完成此操作后,另一個函數將打印出array []中的內容,而現在,隨着我的展開,輸出結果是不相同的。 任何幫助表示贊賞。

更新:我修復了它。 我用這個問題的答案來展開……輸出不匹配,因為我沒有在做array[k] = 0; 在第一個for循環之后。

謝謝,克里斯托

   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截斷為4的整數(N-N%4)

我認為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]時,該索引會導致無限循環。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM