Intel® Fortran Compiler 17.0 Developer Guide and Reference
Statement: Marks the beginning of a CRITICAL construct. A CRITICAL construct limits execution of a block to one image at a time.
[name:] CRITICAL
block
END CRITICAL [name]
name |
(Optional) Is the name of the CRITICAL construct. |
block |
Is a sequence of zero or more statements or constructs. |
If a construct name is specified in a CRITICAL statement, the same name must appear in the corresponding END CRITICAL statement. If no name is specified at the beginning of a CRITICAL statement, you cannot specify one following the END CRITICAL statement. The same construct name must not be used for different named constructs in the same scoping unit.
The block of a CRITICAL construct must not contain a RETURN statement or an image control statement.
A branch within a CRITICAL construct must not have a branch target that is outside the construct.
Execution of the CRITICAL construct is completed when execution of its block is completed. A procedure that is invoked, directly or indirectly, from a CRITICAL construct must not execute an image control statement.
The processor ensures that once an image has commenced executing block, no other image can start executing block until this image has completed executing block. The image must not execute an image control statement during the execution of block. The sequence of executed statements is therefore a segment. If image S is the next to execute the construct after image N, the segment on image N precedes the segment on image S.
If more than one image executes the block of a CRITICAL construct, its execution by one image always precedes or succeeds its execution by another image. Normally no other statement ordering is needed.
Consider the following example:
CONA: CRITICAL
MY_COUNTER[1] = MY_COUNTER[1] + 1
END CRITICAL CONA
The definition of MY_COUNTER [1] by a particular image will always precede the reference to the same variable by the next image to execute the block.
The following example shows a way to share a large number of tasks among images:
INTEGER :: NUMBER_TASKS[*], TASK
IF (THIS_IMAGE() == 1) READ(*,*) NUMBER_TASKS
SYNC ALL
DO
CRITICAL
TASK = NUMBER_TASKS[1]
NUMBER_TASKS[1] = TASK - 1
END CRITICAL
IF (TASK > 0) THEN
ELSE
EXIT
END IF
END DO
SYNC ALL