[英]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.