Intel® Advisor Help
This topic provides advanced examples of 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 Classic or the Intel® Fortran Compiler Classic.
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;
}