User Guide

Contents

Parallelize Data - OpenMP Loops with Complex Iteration Control

Sometimes the loop control is spread across complex control flow. Using OpenMP in this situation requires more features than the simple loops. The task body must not access any of the auto variables defined within the annotation site, because they may have been destroyed before or while the task is running. Also, note that variables referenced within the
task
construct default to
firstprivate
.
Consider this serial C/C++ code:
extern char a[]; int previousEnd = -1; ANNOTATE_SITE_BEGIN(sitename); for (int i=0; i<=100; i++) { if (!a[i] || i==100) { ANNOTATE_TASK_BEGIN(do_something); DoSomething(previousEnd+1,i); ANNOTATE_TASK_END(); previousEnd=i; } } ANNOTATE_SITE_END();
This is done using the OpenMP
task
pragma. Without using this feature, such loops are extremely difficult to parallelize. One approach to the adding parallelism to the loop is to simply spawn each call to
DoSomething()
:
extern char a[]; int previousEnd = -1; #pragma omp parallel { #pragma omp single { ... for (int i=0; i<=100; i++) { if (!a[i] || i==100) { #pragma omp task DoSomething(previousEnd+1,i); } } } }
It is important that the parameters to
DoSomething
be passed by value, not by reference, because
previousEnd
and
i
can change before or while the spawned task runs.
Consider this serial Fortran code:
. . . logical(1) a(200) integer(4) i, previousEnd ... previousEnd=0 call annotate_site_begin(functions) do i=1,101 if a(.not. a(i)) .or. (i .eq. 101) then call annotate_task_begin(do_something) call DoSomething(previousEnd+1, i) call annotate_task_end endif end do call annotate_site_end
This is easily done using the OpenMP
task
directive. Without using this feature, such loops are extremely difficult to parallelize. One approach to the parallelize the above loop is simply to spawn each call to
DoSomething()
:
. . . logical(1) a(200) integer(4) i, previousEnd ... previousEnd=0 !$omp parallel !$omp single do i=1,101 if a(.not. a(i)) .or. (i .eq. 101) then !$omp task call DoSomething(previousEnd+1, i) !$omp end task endif end do !$omp end parallel    
There is no requirement that the
omp task
pragma or directive be within the surrounding parallel directive's static extent.

Product and Performance Information

1

Intel's compilers may or may not optimize to the same degree for non-Intel microprocessors for optimizations that are not unique to Intel microprocessors. These optimizations include SSE2, SSE3, and SSSE3 instruction sets and other optimizations. Intel does not guarantee the availability, functionality, or effectiveness of any optimization on microprocessors not manufactured by Intel. Microprocessor-dependent optimizations in this product are intended for use with Intel microprocessors. Certain optimizations not specific to Intel microarchitecture are reserved for Intel microprocessors. Please refer to the applicable product User and Reference Guides for more information regarding the specific instruction sets covered by this notice.

Notice revision #20110804