User Guide

Contents

Advanced OpenMP Atomic Operations

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
.
After you rewrite your code to use OpenMP* parallel framework, you can analyze its performance with
Intel® Advisor
perspectives. Use the
Vectorization and Code Insights
perspective to analyze how well you OpenMP code is vectorized or use the
Offload Modeling
perspective to model its performance on a GPU.

Example Using the
read
and
write
Clauses

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

Example Using the Basic
capture
Clause

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; } }

Example Using the Swap Form of the
capture
Clause

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; }

Product and Performance Information

1

Performance varies by use, configuration and other factors. Learn more at www.Intel.com/PerformanceIndex.