Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28454 Discussions

Are !$OMP ATOMIC directives necessary in an !$OMP CRITICAL region?

OP1
New Contributor II
327 Views

The following code snippet is located inside a !$OMP PARALLEL region. THIS_THREAD and LOCAL_FAILED_THREAD are private variables, FAILED_THREAD is a shared variable.

I am wondering if it is truly necessary to use the !$OMP ATOMIC directives inside the !$OMP CRITICAL region. The intent here is to guarantee memory consistency between what each local thread thinks FAILED_THREAD is; but maybe the mere fact that the access (read or write) to FAILED_THREAD is inside the !$OMP CRITICAL region is sufficient in itself to guarantee this?

    THIS_THREAD = OMP_GET_THREAD_NUM()

    !$OMP CRITICAL
    !$OMP ATOMIC READ
    LOCAL_FAILED_THREAD = FAILED_THREAD
    !$OMP END ATOMIC
    IF (LOCAL_FAILED_THREAD==-1) THEN
        LOCAL_FAILED_THREAD = THIS_THREAD
        !$OMP ATOMIC WRITE
        FAILED_THREAD = LOCAL_FAILED_THREAD
        !$OMP END ATOMIC
    END IF
    !$OMP END CRITICAL


    IF (THIS_THREAD==LOCAL_FAILED_THREAD) THEN
    ! Do some work here.
    END IF

 

0 Kudos
5 Replies
jimdempseyatthecove
Honored Contributor III
327 Views

On Intel processors IA32 and Intel64 (but not necessarily IA64 and not necessarily some other processors) the above atomics may be unnecessary. A cleaner solution would be to use FLUSH

THIS_THREAD = OMP_GET_THREAD_NUM()

!$OMP CRITICAL
!$OMP FLUSH(FAILED_THREAD)
LOCAL_FAILED_THREAD = FAILED_THREAD
IF (LOCAL_FAILED_THREAD==-1) THEN
    LOCAL_FAILED_THREAD = THIS_THREAD
    FAILED_THREAD = LOCAL_FAILED_THREAD
!$OMP FLUSH(FAILED_THREAD)
END IF
!$OMP END CRITICAL


IF (THIS_THREAD==LOCAL_FAILED_THREAD) THEN
! Do some work here.
END IF

Jim Dempsey

0 Kudos
jimdempseyatthecove
Honored Contributor III
327 Views

Note, the code provided is indicative that FAILED_THREAD is read elsewhere. Where it is read may require !$OMP FLUSH(FAILED_THREAD) as well.

Jim Dempsey

0 Kudos
IanH
Honored Contributor II
327 Views

Flush is implied at a number of locations, including the entry and exit of a critical region (OpenMP 4.5 p168).

If all reads and writes of FAILED_THREAD are within that critical construct then ATOMIC is not required.

0 Kudos
OP1
New Contributor II
327 Views

Thanks to all for the clarification!

0 Kudos
jimdempseyatthecove
Honored Contributor III
327 Views

>>Flush is implied at a number of locations, including the entry and exit of a critical region (OpenMP 4.5 p168).

Depending on the rest of the code, it may or may not require more immediate notification than that at the end of the parallel region. This is a design consideration.

Jim Dempsey

0 Kudos
Reply