Previous: Structured Parallel Blocks: par Up: Structured Parallel Blocks: par Next: Structuring

Introduction

The most basic mechanism for creating parallel threads of control in CC++ is the parallel block. A parallel block looks just like a compound statement in C or C++ with the keyword par in front of it:

par  {
  statement_1; 
  statement_2; 
  ...
  statement_N 
}

Except for a few cases, the statements inside a parallel block can be any legal C, C++, or CC++ statement. The exceptions are variable declarations and statements that result in nonlocal changes in the flow of control. These limitations will be discussed in more detail in the ``Pitfalls'' section of this chapter ().

A parallel block differs from the normal C block in that the order in which the statements in the block execute is not defined: an execution of a parallel block is an interleaved or possibly concurrent execution of the statements within the block. The execution of a parallel block is finished after all of the statements within the block have finished executing. Consequently, statements after a parallel block will not start to execute until all the statements within the parallel block terminate.

We do know some things about how the operations in a parallel block are mixed together. We know that the order of operations within any one statement in the parallel block is preserved. We also know that regardless of how long it may take any statement to finish, each statement in the block will eventually get a chance to execute. We call the type of execution that occurs in a parallel block a fair interleaving. There are some pragmatic issues having to do with implementing fair interleaving. If you have an application that depends on fairness, you should consult the Appendix for the particular hardware platforms you are using to get the details.

Let us look at some parallel blocks.


{
  int a, b, d; 
  c = 1; 
  par  { 
    a = 2; 
    b = c+3; 
  } 
  d = b+1;
}

The parallel block in this example has two independent threads of control: the first assigns the value 2 to the integer variable a and the second evaluates the sum c+3 and assigns this value to the integer variable b. The statement assigning the value to d does not execute until both assignments to a and b have completed. This flow of control is illustrated in Figure .

The statements contained in a parallel block can be function calls, such as:


par  {
  g = gcd(a,b);
  l = lcm(a,b); 
  s = sum(a,b); 
}

paolo@cs.caltech.edu