Intel® Fortran Compiler 17.0 Developer Guide and Reference
OpenMP* Fortran Compiler Directive: Specifies a block of code that the threads in a team must execute in the natural order of the loop iterations, or, as a stand-alone directive, it specifies cross-iteration dependences in a doacross loop nest.
It takes one of the following forms:
Form 1:
!$OMP ORDERED [clause [[,] clause ]]
block
!$OMP END ORDERED
Form 2:
!$OMP ORDERED clause [[[,] clause ]...]
Form 1 clause |
Is an optional clause. It can be one of the following:
At most one THREADS clause can appear in an ORDERED construct. At most one SIMD clause can appear in an ORDERED construct. |
Form 2 clause |
Is one of the following:
|
block |
Is a structured block (section) of statements or constructs. You cannot branch into or out of the block. |
The binding thread set for an ORDERED construct is the current team. An ordered region binds to the innermost enclosing loop region or the innermost enclosing SIMD region if the SIMD clause is present.
An ORDERED directive with no clause or with the THREADS clause specified can appear only in the dynamic extent of a DO or PARALLEL DO directive. The DO directive to which the ordered section binds must have the ORDERED clause specified.
An iteration of a loop using a DO directive must not execute the same ORDERED directive more than once, and it must not execute more than one ORDERED directive.
One thread is allowed in an ordered section at a time. Threads are allowed to enter in the order of the loop iterations. No thread can enter an ordered section until it can be guaranteed that all previous iterations have completed or will never execute an ordered section. This sequentializes and orders code within ordered sections while allowing code outside the section to run in parallel.
Ordered sections that bind to different DO directives are independent of each other.
If the SIMD clause is specified, the ordered regions encountered by any thread will use only a single SIMD lane to execute the ordered regions in the order of the loop iterations.
You can only specify the SIMD clause (!$OMP ORDERED SIMD) within an !$OMP SIMD loop or an !$OMP DECLARE SIMD procedure.
When a thread executing any subsequent iteration encounters an ORDERED construct with one or more DEPEND (SINK : vec) clauses, it waits until its dependences on all valid iterations specified by the DEPEND clauses are satisfied before it completes execution of the ORDERED region. A specific dependence is satisfied when a thread executing the corresponding iteration encounters an ORDERED construct with a DEPEND (SOURCE) clause.
Ordered sections are useful for sequentially ordering the output from work that is done in parallel. Assuming that a reentrant I/O library exists, the following program prints out the indexes in sequential order:
!$OMP DO ORDERED SCHEDULE(DYNAMIC)
DO I=LB,UB,ST
CALL WORK(I)
END DO
...
SUBROUTINE WORK(K)
!$OMP ORDERED
WRITE(*,*) K
!$OMP END ORDERED
Ordered SIMD sections are useful for resolving cross-iteration data dependencies in otherwise data-parallel computations. For example, it may handle histogram updates such the following:
!$OMP SIMD
DO I=0,N
AMOUNT = COMPUTE_AMOUNT(I)
CLUSTER = COMPUTE_CLUSTER(I) ! Multiple I’s may belong to the
! same cluster within SIMD chunk
!$OMP ORDERED SIMD
TOTALS(CLUSTER) = TOTALS(CLUSTER) + AMOUNT ! Requires ordering to
! process multiple updates
! to the same cluster
!$OMP END ORDERED
END DO
!$OMP END SIMD