我正在尝试使用OpenMP以并行方式在双精度数组中编写(更新).我们的想法是,需要更新的元素可以多次更新,并且元素本身可以即时计算.这使得它非常容易出现竞争条件,除非我"锁定"与使用原子操作更新的元素相对应的内存区域.如下例所示:
#include<omp.h>
#include<stdlib.h>
int main()
{
double *x=NULL, contribution = 1234.5;
size_t xlen=1000, i, n;
if ( (x = (double *) calloc(xlen,sizeof(double)) ) == NULL) exit(-1)
#pragma omp parallel for shared(x) private(n,contribution)
for (i=0; i<xlen; i++) {
n = find_n_on_the_fly(i);
#pragma omp atomic update
x[n]+=contribution; // in the more complicated case contributions are different
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我仍然在用这种方法遇到竞争条件.我尝试使用关键部分,但它完全杀了我,因为数组很大,更新的数量也很大.
问题:这种方法有什么问题?有没有更好的方法来处理这个?
注意:为了解决这个问题,我通过为每个线程创建数组的副本并在以后减少它们来做一些愚蠢的事情.但内存限制不允许我走得更远.
我将用“我对并行计算非常陌生”作为序言,这可能不可行,具体取决于您的用例。
一种可能有用的想法是将程序的计算和更新方面分开。建立一个主/控制进程/线程,它可以唯一访问该阵列,并根据从从/计算进程/线程收集的信息以队列方式执行更新。这可以最大限度地减少传统意义上的锁定需求。
我希望这至少提供了一种看待问题的不同方式。