quant
quant

Reputation: 23052

how to work on a task while remaining threads finish working

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

Answers (1)

Massimiliano
Massimiliano

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:

  1. a loop construct at #2
  2. a single construct at #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

Related Questions