我正在尝试并行化这个包含" serial"的4-nested循环。 counter
问题。
count = 0
for (i = 0; i < vel; i++)
for (n = 0; n < dist; n++)
for (j = 1; j <= Y; j++)
for (k = 1; k <= Z; k++) {
index = index(X, j, k);
buffX[count] = array[index];
index = index(Y, j, k);
buffY[count] = array[index];
++count;
}
我尝试过非常简单的想法,例如:
#pragma omp parallel for private(i,n,j,k,index) shared(count)
for (i = 0; i < vel; i++)
for (n = 0; n < dist; n++)
for (j = 1; j <= Y; j++)
#pragma omp critical
{
for (k = 1; k <= Z; k++) {
index = index(X, j, k);
buffX[count] = array[index];
index = index(Y, j, k);
buffY[count] = array[index];
++count;
}
}
但由于count
,它无效。我想知道是否有众所周知的技术来并行化这种循环。
答案 0 :(得分:1)
直接的方法是从嵌套循环变量计算threadlocal count
变量:
for (i = 0; i < vel; i++)
for (n = 0; n < dist; n++)
for (j = 1; j <= Y; j++)
for (k = 1; k <= Z; k++) {
int count = (k-1) + Z * ((j-1) + Y * (n + dist * i));
...
如果您担心额外费用,可以在中间设置一些中间count_j
。
另一种方法是手动折叠循环并使count
成为主循环索引:
#pragma omp parallel for
for (count = 0; count < vel * dist * Y * Z; count++) {
// declare locally to make sure they are threadlocal
int k = 1 + (count % Z);
...
请注意,这可能会积极地影响循环的并行性能(更多迭代,更好的平衡)或负面影响(错误的缓存效果)。
一个解决方案,整个循环体只是一个关键部分将是可怕的。没有线程可以并行执行任何计算(或内存传输)。除了关键区域没有引入订单保证,使代码错误。