OpenMP在同一块内存中并发写入

时间:2018-01-23 12:34:28

标签: c parallel-processing openmp

假设有两个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;
} 

1 个答案:

答案 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。 哪一个更适合您取决于更新速率和矩阵的大小。你必须测量两者才能确定。