I have being trying to write(update) in an array of doubles in a parallel way using OpenMP. The idea is that the element that needs to be updated can be updated more than once and the element itself is computed on-the-fly. This makes it very prone to race conditions unless I "lock" the memory region correspondent to the element that is being updated with an atomic operation. As the example below:
#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;
}
I am running into race conditions with this approach still. I tried using critical sections but it completely kills me since the arrays are large and the number of updates is also large.
Question: what is wrong with this approach? Is there a better way of handling this?
Note: To handle this I am doing something stupid, by creating copies of the arrays for each one of the threads and reducing them later. But memory limitations don't allow me to go further.