Intel® Advisor Help
This topic provides advanced examples of OpenMP atomic operations. For basic information about OpenMP atomic operations, see Basic OpenMP Atomic Operations.
These advanced atomic operations use clauses after the atomic construct, such as read, write, update, capture, and seq_cst. If you do not add a clause after atomic, the default is update.
Because these clauses are part of OpenMP 3.1 and 4.0 specification, you need a compiler that supports these advanced atomic clauses, such as the Intel C++ Compiler or the Intel Fortran Compiler.
The following C/C++ example uses separate read and write clauses:
int atomic_read(const int *x) { int value; /* Ensure that the entire value of *x is read atomically. */ /* No part of *x can change during the read operation. */ #pragma omp atomic read value = *x; return value; } void atomic_write(int *x, int value) { /* Ensure that value is stored atomically into *x. */ /* No part of *x can change until after the entire write operation has completed. */ #pragma omp atomic write *x = value; }
The following Fortran example uses the read and write clauses:
function atomic_read(x) integer :: atomic_read integer, intent(in) :: x ! Ensure that the entire value of x is read atomically. No part of x can change during ! the read operation. !$omp atomic read atomic_read = x return end function atomic_read subroutine atomic_write(x, value) integer, intent(out) :: x integer, intent(in) :: value ! Ensure that value is stored atomically into x. No part of x can change ! until after the entire write operation has completed. !$omp atomic write x = value end subroutine atomic_write
The following C/C++ example uses the capture clause:
#pragma omp parallel for shared (pos) for (int i=0; i < size; i++) { if (isValid(data[i])) { int tmpPos; // Using omp atomic capture pragma #pragma omp atomic capture { tmpPos = pos; pos = pos+1; } //Pack all selected element' indices in index; exact order of indices values is not important. index[tmpPos] = i; } }
The capture clause example above might be modified to use the following code snippet:
//with introduction of “atomic swap” you can also use forms like: newPos = foo(); . . . #pragma omp atomic capture { tmpPos = pos; pos = newPos; }