Search code examples
c++multithreadingparallel-processingopenmpreduction

OpenMP: Is array reduction always needed for updating an array in parallel?


I am quite new to OpenMP. I have the following simple loop that I want to run in parallel with OpenMP:

double rij[3];
double r;

#ifdef _OPENMP
#pragma omp parallel for private(rij,r)
#endif
for (int i=0; i<n; ++i)
{
    for (int j=0; j<n; ++j)
    {
        if (i != j)
        {
            distance(X,rij,r,i,j);

            V[i] += ke * Q[j] / r;

            for (int k=0; k<3; ++k)
            {
                F[3*i+k] += ke * Q[j] * rij[k] / pow(r,3);
            }
        }
    }
}

From what I understood, variables are shared by default which is why I only declared private(rij,r). But according to these questions (first second third), I should do array reduction in this case.

It's clear to me that if many threads need to sum to the same variable, this has to be done with #pragma omp parallel for reduction(+:A[:n]) for summing to array A of size n. This is what I do in another part of my code, and it works as expected.

However, in this case workers never have to sum to the same variable: every worker performs the sum on its index i. Is is correct to do as I do in this case i.e. not doing any array reduction and not using any critical section ?

If my implementation is correct, I believe it would avoid the overhead of the critical section while being simpler code. Feel free to give your advice on how this could be better optimized.

Thank you


Solution

  • You don't need a reduction. It is a feature to avoid copying the same code all over again because they are re-occurring problems (Try to think off, how you would implement a sum-reduction without OpenMP).

    What you do right now is working on parallel data (V[i]) which should not overlap at any iteration (as you state in the question), because you divide by i itself. Furthermore write to F[...] shouldn't overlap either, because it only depends on iand k