Waiting
for Work to Complete
For most parallel constructs, there is an implicit barrier at the end to
ensure that all threads complete their work before the next block of code is
started. This section describes the options in OpenMP for changing the default
barrier behavior.
Allowing
Threads to Continue Execution Beyond a Parallel Region
The nowait clause
applies to parallel for, parallel
sections, and single direc-tives. All of these directives have an implied wait at the end of
the parallel region. Use of the directive means that the threads in the
parallel region will continue into the next code region once they have
completed the current one without waiting for the other worker threads to
complete their work. Listing 7.49 contains an example of two for loops that iterate over two different ranges on two different sets of
variables. Once the threads have completed the first loop, there is no reason
why they should not start work on the second loop. This preference can be
denoted by labeling the first loop with the nowait clause. The second loop keeps the implicit wait clause, so execution
will not continue until all the threads
complete their work on the second loop.
Listing 7.49 Using
the nowait Clause
double
calc( double *a, int lena, double *b, int lenb )
{
double totala = 0.0, totalb = 0.0; #pragma omp parallel
{
#pragma omp for nowait
reduction( +: totala ) for ( int i=0; i<lena; i++ )
{
totala += a[i];
}
#pragma omp for reduction( +:totalb ) for ( int
i=0; i<lenb; i++ )
{
totalb += b[i];
}
}
return totala + totalb;
}
Causing
Threads to Wait Until All the Threads Have Completed Their Work
The barrier
directive places an explicit barrier in a parallel region. In Listing 7.50, the
barrier directive
is used with the master directive
to ensure that all threads wait while the master thread completes its task. The master directive does not have an implicit wait clause, so without the barrier
directive, the single thread may print its output before the master thread.
With this barrier in place, the code will always print out the string
"Master
thread" before it prints the string
"Single thread".
Listing 7.50 Using the barrier Directive to Cause Other Threads to Wait for Master Thread
#include <stdio.h>
int main()
{
#pragma omp
parallel
{
#pragma omp
master
{
printf( "Master thread\n" );
}
#pragma omp
barrier #pragma omp single
{
printf( "Single thread\n" );
}
}
}
Waiting
for All Child Tasks to Complete
When an application has been parallelized using tasks, it can be useful
to wait for all the current child tasks from a parallel region to complete
before continuing execution. The taskwait directive ensures that this condition is met. Consider the code shown in
Listing 7.51.
Listing 7.51 Using
the taskwait Directive Wait for Child
Tasks to Complete
#include <stdio.h>
int work( int i )
{
if ( i > 0 )
{
#pragma omp
parallel
{
#pragma omp
task
{
work( i-1 );
}
#pragma omp
task
{
work( i-1 );
}
#pragma omp taskwait
printf( "Completed %i\n", i );
}
}
}
void
main()
{
work( 3 );
}
In this example, the taskwait directive is used to ensure that the child tasks com-plete before the
parent task performs its work, which is printing the value of the variable i. In the absence of the taskwait directive,
it would be possible for the parent task to print its output before the child tasks printed theirs. Listing 7.52
shows the output from this application.
Listing 7.52 Output Showing Effect of Task Wait on Ordering of Task Execution
% cc -O -xopenmp -xloopinfo taskwait.c
% ./a.out
Completed
1
Completed
1
Completed
2
Completed
1
Completed
1
Completed
2
...
Related Topics
Privacy Policy, Terms and Conditions, DMCA Policy and Compliant
Copyright © 2018-2023 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.