Parallel Processing Thread Model

This topic explains the processing of the parallelized program and adds more definitions of the terms used in parallel programming.

The Execution Flow

As previously mentioned, a program containing OpenMP* C++ API compiler directives begins execution as a single process, called the master thread of execution. The master thread executes sequentially until the first parallel construct is encountered.

In the OpenMP C++ API, the #pragma omp parallel directive defines the parallel construct. When the master thread encounters a parallel construct, it creates a team of threads, with the master thread becoming the master of the team. The program statements enclosed by the parallel construct are executed in parallel by each thread in the team. These statements include 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 the static extent as well as the routines called from within the construct. When the #pragma omp parallel directive reaches completion, the threads in the team synchronize, the team is dissolved, and only the master thread continues execution. The other threads in the team enter a wait state. 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.

Using Orphaned Directives

In routines called from within parallel constructs, you can also use directives. Directives that are not in the lexical extent of the parallel construct, but are in the dynamic extent, are called orphaned directives. Orphaned directives allow you to execute major 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 and use directives to control execution in any of the called routines. For example:

int main(void)

{

   ...

   #pragma omp parallel

   {

      phase1();

   }

}

 

void phase1(void)

{

   ...

   #pragma omp for private(i) shared(n)

   for(i=0; i < n; i++)

   {

      some_work(i);

   }

}

This is an orphaned directive because the parallel region is not lexically present.

Data Environment Directive

A data environment directive controls the data environment during the execution of parallel constructs. You can control the data environment within parallel and worksharing constructs. Using directives and data environment clauses on directives, you can:

You can use several directive clauses to control the data scope attributes of variables for the duration of the construct in which you specify them. If you do not specify a data scope attribute clause on a directive, the default is SHARED for those variables affected by the directive.

Pseudo Code of the Parallel Processing Model

A sample pseudo program using some of the more common OpenMP directives is shown in the code example that follows. This example also indicates the difference between serial regions and parallel regions.

main() {

// Begin serial execution

 ...

// Only the master thread executes

#pragma omp parallel

// Begin a Parallel Construct, form

 {

// a team. This is Replicated Code

  ...

// (each team member executes

  ...

// the same code)

 

//

#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

 ...

// More Replicated Code

 

//

 #pragma omp for nowait

// Begin a Worksharing Construct;

  for(...) {

// each iteration 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

 {

//

  ...

// Replicated Code, but only one

 

// thread can execute it at a

 }

// given time

 ...

// More Replicated Code

 

//

 #pragma omp barrier

// Wait for all team members to arrive

 ...

// More Replicated Code

 

//

}

// End of Parallel Construct;

 

// disband team and continue

 

// serial execution

 

//

...

// Possibly more Parallel constructs

 

//

}

// End serial execution