Reputation: 23052
Suppose I have an OpenMP 2.0 for loop that runs some operation:
#pragma omp parallel for schedule(static)
for (int i = 0; i < lim; ++i)
{
// do something thread-safe
}
threadSafeFunc();
unSafeFunc();
The functor threadSafeFunc
is completely thread-safe so rather than running it serially after all those iterations are finished, I would like to get the first thread that finishes its allocation of tasks from the OpenMP loop to start working on it, and then for all threads to wait before executing unSafeFunc
in serial.
How do I do this?
Upvotes: 0
Views: 356
Reputation: 8032
This may be a solution to your particular issue:
#pragma omp parallel
{ // #1
#pragma omp for schedule(static) nowait
for (int i = 0; i < lim; ++i) // #2
{
// do something thread-safe
} // No implied barrier bue to the nowait clause
#pragma omp single
{ // #3
threadSafeFunc();
} // Implied barrier
} // End of parallel region
unSafeFunc();
The idea is quite simple: you first open a parallel
region in #1
. Inside this parallel region you use two worksharing constructs:
#2
#3
The loop construct (section 2.7.1 of the standard) has a nowait
clause that removes the implicit barrier at the end of the loop. Then the single
construct (section 2.7.3):
... specifies that the associated structured block is executed by only one of the threads in the team (not necessarily the master thread), in the context of its implicit task. The other threads in the team, which do not execute the block, wait at an implicit barrier at the end of the single ...
The combination of the two constructs ensures that the first thread finishing its work in the loop will enter the single
construct and execute threadSafeFunc()
. Then all the threads will synchronize at the implied barrier and join with the master
thread. At this point only the master
thread will proceed and execute unSafeFunc()
.
Upvotes: 3