Reputation: 379
I have an OpenMP loop where I want the first iteration to complete before any of the other threads continue. I've tried using a global variable, initialized to 'false', which is set to 'true' when the first iteration finishes, but this doesn't appear to work as expected (I get stuck in an infinite loop).
For example:
bool FirstDone = false; // This is a global variable
...
#pragma omp parallel for
for(int i=0;i<max;i++)
{
while(!FirstDone && i>0){}
if(i==0)
{
// Do something
FirstDone = true;
}
}
Can anyone shed light on why this isn't working?
Upvotes: 0
Views: 1875
Reputation: 8032
I'll try here to rephrase the answer of @HighPerformanceMark in a more explicit manner (i.e. with some code sketches to support statements). Just to fix ideas, let's say that a serial version of your loop looks like:
for(int ii = 0; ii < max; ii++)
{
// Do a lot of work based on ii
if(ii==0)
{
//////////////////////////////////////////////////
// Do something special for the first iteration //
//////////////////////////////////////////////////
}
}
What was briefly proposed in a previous answer was to parallelize it with this simple logic
// Move the loop body into a function
void loopIteration(const size_t ii) {
// Do a lot of work based on ii
}
#pragma omp parallel
{
// Single directive: the first one enters, the other wait at the implicit barrier
#pragma omp single
{
loopIteration(0);
//////////////////////////////////////////////////
// Do something special for the first iteration //
//////////////////////////////////////////////////
} // single: implicit barrier
// Loop work-sharing construct on the remaining iterations
#pragma omp for
for(int ii = 1; ii < max; ii++)
{
loopIteration(ii);
} // for: implicit barrier
} // parallel
The main ideas are to move the loop body into a function to avoid code duplication and to unroll explicitly the first iteration from the loop.
Upvotes: 2
Reputation: 59072
Have you tried simply removing the.empty while loop and setting a barrier after the if statement ?
Upvotes: 0
Reputation: 36402
I think you can achieve this by using an ordered
clause and region, eg.
#pragma omp parallel for ordered
for(int i=0;i<max;i++)
{
#pragma omp ordered
if (i == 0)
{
// Do stuff in the first iteration, others wait.
}
}
This may incur a performance overhead.
Upvotes: 1
Reputation: 78316
You could wrap the first iteration inside an OpenMP single
construct. This will ensure that the first thread to encounter the construct will execute it and that all the other threads will wait until it is finished before continuing with the rest of the computation.
Upvotes: 2
Reputation: 1752
Use this one
#pragma omp parallel for
it starts by default with your first iteration.
Upvotes: 1
Reputation: 24146
do first iteration outside the loop, start for with i=1, if you want to proceed with your logic, change FirstDone to volatile, but it still will not work, as there is no guarantee of thread ordering
Upvotes: 2