HOME
| OPENMP API Specification: Version 5.1 November 2020

2.19.8  flush Construct

Summary The flush construct executes the OpenMP flush operation. This operation makes a thread’s temporary view of memory consistent with memory and enforces an order on the memory operations of the variables explicitly specified or implied. See the memory model description in Section 1.4 for more details. The flush construct is a stand-alone directive.

Syntax

SVG-Viewer needed.

The syntax of the flush construct is as follows:  

 
#pragma omp flush [memory-order-clause] [(list)] new-line  

where memory-order-clause is one of the following:  

 
seq_cst 
acq_rel 
release 
acquire  

SVG-Viewer needed.

SVG-Viewer needed.

The syntax of the flush construct is as follows:  

 
!$omp flush [memory-order-clause] [(list)]  

where memory-order-clause is one of the following:  

 
seq_cst 
acq_rel 
release 
acquire  

SVG-Viewer needed.

Binding The binding thread set for a flush region is all threads in the device-set of its flush operation. Execution of a flush region affects the memory and it affects the temporary view of memory of the encountering thread. It does not affect the temporary view of other threads. Other threads on devices in the device-set must themselves execute a flush operation in order to be guaranteed to observe the effects of the flush operation of the encountering thread.

Description If neither memory-order-clause nor a list appears on the flush construct then the behavior is as if memory-order-clause is seq_cst.

A flush construct with the seq_cst clause, executed on a given thread, operates as if all data storage blocks that are accessible to the thread are flushed by a strong flush operation. A flush construct with a list applies a strong flush operation to the items in the list, and the flush operation does not complete until the operation is complete for all specified list items. An implementation may implement a flush construct with a list by ignoring the list and treating it the same as a flush construct with the seq_cst clause.

If no list items are specified, the flush operation has the release and/or acquire flush properties:

SVG-Viewer needed.

If a pointer is present in the list, the pointer itself is flushed, not the memory block to which the pointer refers.

A flush construct without a list corresponds to a call to atomic_thread_fence, where the argument is given by the identifier that results from prefixing memory_order_ to memory-order-clause.

For a flush construct without a list, the generated flush region implicitly performs the corresponding call to atomic_thread_fence. The behavior of an explicit call to atomic_thread_fence that occurs in the program and does not have the argument memory_order_consume is as if the call is replaced by its corresponding flush construct.

SVG-Viewer needed.

SVG-Viewer needed.

If the list item or a subobject of the list item has the POINTER attribute, the allocation or association status of the POINTER item is flushed, but the pointer target is not. If the list item is a Cray pointer, the pointer is flushed, but the object to which it points is not. Cray pointer support has been deprecated. If the list item is of type C_PTR, the variable is flushed, but the storage that corresponds to that address is not flushed. If the list item or the subobject of the list item has the ALLOCATABLE attribute and has an allocation status of allocated, the allocated variable is flushed; otherwise the allocation status is flushed.

SVG-Viewer needed.

SVG-Viewer needed.

Note – Use of a flush construct with a list is extremely error prone and users are strongly discouraged from attempting it. The following examples illustrate the ordering properties of the flush operation. In the following incorrect pseudocode example, the programmer intends to prevent simultaneous execution of the protected section by the two threads, but the program does not work properly because it does not enforce the proper ordering of the operations on variables a and b. Any shared data accessed in the protected section is not guaranteed to be current or consistent during or after the protected section. The atomic notation in the pseudocode in the following two examples indicates that the accesses to a and b are atomic write and atomic read operations. Otherwise both examples would contain data races and automatically result in unspecified behavior. The flush operations are strong flushes that are applied to the specified flush lists

Incorrect example:       a = b = 0

    thread 1

    thread 2

  

atomic(b = 1)

atomic(a = 1)

flush(b)

flush(a)

flush(a)

flush(b)

atomic(tmp = a)

atomic(tmp = b)

if (tmp == 0) then

if (tmp == 0) then

  protected section

  protected section

end if

end if

The problem with this example is that operations on variables a and b are not ordered with respect to each other. For instance, nothing prevents the compiler from moving the flush of b on thread 1 or the flush of a on thread 2 to a position completely after the protected section (assuming that the protected section on thread 1 does not reference b and the protected section on thread 2 does not reference a). If either re-ordering happens, both threads can simultaneously execute the protected section.

The following pseudocode example correctly ensures that the protected section is executed by only one thread at a time. Execution of the protected section by neither thread is considered correct in this example. This occurs if both flushes complete prior to either thread executing its if statement.

Correct example:       a = b = 0

    thread 1

    thread 2

  

atomic(b = 1)

atomic(a = 1)

flush(a,b)

flush(a,b)

atomic(tmp = a)

atomic(tmp = b)

if (tmp == 0) then

if (tmp == 0) then

  protected section

  protected section

end if

end if

The compiler is prohibited from moving the flush at all for either thread, ensuring that the respective assignment is complete and the data is flushed before the if statement is executed.

SVG-Viewer needed.

Execution Model Events The flush event occurs in a thread that encounters the flush construct.

Tool Callbacks A thread dispatches a registered ompt_callback_flush callback for each occurrence of a flush event in that thread. This callback has the type signature ompt_callback_flush_t.

Restrictions Restrictions to the flush construct are as follows:

Cross References

2.19.8.1 Implicit Flushes

Flush operations implied when executing an atomic region are described in Section 2.19.7.

A flush region that corresponds to a flush directive with the release clause present is implied at the following locations:

For a target construct, the device-set of an implicit release flush that is performed in a target task during the generation of the target region and that is performed on exit from the initial task region that implicitly encloses the target region consists of the devices that execute the target task and the target region.

A flush region that corresponds to a flush directive with the acquire clause present is implied at the following locations:

For a target construct, the device-set of an implicit acquire flush that is performed in a target task following the generation of the target region or that is performed on entry to the initial task region that implicitly encloses the target region consists of the devices that execute the target task and the target region.

SVG-Viewer needed.

Note – A flush region is not implied at the following locations:

SVG-Viewer needed.

The synchronization behavior of implicit flushes is as follows: