假设有两个3D阵列:A和B,每个都有不同数量的元素。我使用A值进行一些操作,这些操作对应于具有不同索引的B的某些值。
例如:我使用A[i][j][k]
来计算一些数量。由于每次计算都是独立的,我可以使用并行执行此操作,没有任何问题。但更新后的值用于增加B阵列某些位置的值。
例如:
A[i][j][k]->C(a number)->B[l][m][n]
。但与此同时,B[l][m][n]
可能会发生大量写入。我使用B[l][m][n]+=c
来更新B元素。当然我不能在这里使用OpenMP
,因为我违反了循环的独立性。并且我也不知道索引l,l,m的先验,以便将它们分组到缓冲区写入中。关于如何并行实现它的任何好主意?也许批评或原子会让我受益,但我不知道如何
我的问题的简化版本(1D)
for(int i=0,i<size_A,i++)
{
//Some code here to update A[i]. Each update is independent.
}
for(int j=0,j<size_A,j++)
{
//From A[j] B[m],B[m+1] are evaluated
int m=A[j]/dx;
double c;//Make some calculations
B[m] += c;
B[m+1] += c*c;
}
答案 0 :(得分:0)
有两种方法可以做到这一点。您可以进行每次更新atomic
。这看起来像:
#pragma omp atomic update
B[m] += c;
或者每个线程获得B
的私有更新版本,并且在循环之后,私有副本都安全地添加在一起。这可以通过使用:
#pragma omp parallel for reduction(+:B)
for (...)
后者需要OpenMP 4.5,但有workarounds for earlier versions。 哪一个更适合您取决于更新速率和矩阵的大小。你必须测量两者才能确定。