Developer Guide and Reference


Parallel Processing Model

A program containing OpenMP* API compiler
begins execution as a single thread, called the initial thread of execution. The initial thread executes sequentially until the first parallel construct is encountered.
In the OpenMP* API, the
omp parallel
pragma defines
the extent of the parallel construct. When the initial thread encounters a parallel construct, it creates a team of threads, with the initial thread becoming the master of the team. All program statements enclosed by the parallel construct are executed in parallel by each thread in the team, including all routines called from within the enclosed statements.
The statements enclosed lexically within a construct define the static extent of the construct. The dynamic extent includes all statements encountered during the execution of a construct by a thread, including all called routines.
When a thread encounters the end of a structured block enclosed by a parallel construct, the thread waits until all threads in the team have arrived. When that happens the team is dissolved, and only the master thread continues execution of the code following the parallel construct. The other threads in the team enter a wait state until they are needed to form another team. You can specify any number of parallel constructs in a single program. As a result, thread teams can be created and dissolved many times during program execution.
The following example illustrates, from a high level, the execution model for the OpenMP* constructs. The comments in the code explain the structure of each construct or section.
main() { // Begin serial execution. ... // Only the initial thread executes #pragma omp parallel { // Begin a parallel construct and form a team. #pragma omp sections { // Begin a worksharing construct. #pragma omp section // One unit of work. {...} #pragma omp section // Another unit of work. {...} } // Wait until both units of work complete. ... // This code is executed by each team member. #pragma omp for nowait // Begin a worksharing Construct for(...) { // Each iteration chunk is unit of work. ... // Work is distributed among the team members. } // End of worksharing construct. // nowait was specified so threads proceed. #pragma omp critical // Begin a critical section. {...} // Only one thread executes at a time. ... // This code is executed by each team member. #pragma omp barrier // Wait for all team members to arrive. ... // This code is executed by each team member. } // End of Parallel Construct // Disband team and continue serial execution. ... // Possibly more parallel constructs. } // End serial execution.

Using Orphaned

In routines called from within parallel constructs, you can also use
that are not in the static extent of the parallel construct, but are in the dynamic extent, are called orphaned
. Orphaned
allow you to execute portions of your program in parallel with only minimal changes to the sequential version of the program. Using this functionality, you can code parallel constructs at the top levels of your program call tree and use directives to control execution in any of the called routines. For example: