omp atomic

Specifies a computation that must be executed atomically.

Syntax

#pragma omp atomic [read|write|update|capture] [ seq_cst]

expression-stmt

OR

#pragma omp atomic [capture] [ seq_cst]

structured-block

Arguments

read

expression-stmt must be of the form v = x;

write

expression-stmt must be of the form x = expr;

update (or not present)

expression-stmt must be one of the forms:

  • x++;

  • x--;

  • ++x;

  • --x;

  • x binop = expr;

  • x = x binop expr;

  • x = expr binop x;

capture

expression-stmt is one of the following forms if no structured-block is used:

  • v = x++;

  • v = x--;

  • v = ++x;

  • v = --x;

  • v = x binop= expr;

  • x = x binop expr;

  • x = expr binop x;

expression-stmt is one of the following forms if a structured-block is used:

  • {v = x; x binop= expr}

  • {x binop= expr; v = x}

  • {v = x; x = x binop expr;}

  • {v = x; x = exp binop x;}

  • {x = x binop expr; y = x;}

  • {x = expr binop x; y = x;}

  • {v = x; x = expr; }

  • {v = x; x++;}

  • {v = x; ++x;}

  • {++x; y = x;}

  • {x++; y = x;}

  • {v = x; x--;}

  • {y = x; --x;}

  • {--x; y = x;}

  • {x--; y = x;}}

In the above expressions:

  • x and v (as applicable) are both l-value expressions with scalar type.

  • During the execution of an atomic region, multiple syntactic occurrences of x must designate the same storage location.

  • Neither of v and expr (as applicable) may access the storage location designated by x.

  • expr is an expression with scalar type.

  • binop is one of +, *, -, /, &, ^, |, <<, or >>.

  • binop, binop=, ++, and -- are not overloaded operators.

  • The expression x binop expr must be mathematically equivalent to x binop (expr).

  • The expression expr binop x must be mathematically equivalent to (expr) binop x.

  • For forms that allow multiple occurrences of x, the number of times that x is evaluated is unspecified.

Description

The binding thread set for an atomic region is all threads. Atomic regions enforce exclusive access with respect to other atomic regions that access the same storage location x among all the threads in the program without regard to the teams to which the threads belong.

Note that the following restriction applies to the omp atomic pragma : all atomic accesses to the storage locations designated by x throughout the program must have the same type and type parameters.

The following table describes what happens when you specify one of the clauses in an atomic construct.

Clause

Result

read

Causes an atomic read of the location designated by x regardless of the native machine word size.

write

Causes an atomic write of the location designated by x regardless of the native machine word size.

[update]

Causes an atomic update of the location designated by x using the designated operator or intrinsic. The following rules also apply:

  • The evaluation of expr or expr-list need not be atomic with respect to the read or write of the location designated by x.
  • No task scheduling points occur between the read and the write of the location designated by x.

capture

Causes an atomic update of the location designated by x using the designated operator or intrinsic while also capturing the original or final value of the location designated by x with respect to the atomic update. The following rules also apply:

  • The original or final value of the location designated by x is written in the location designated by v, depending on the form of the atomic construct, structured block, or statements, following the usual language semantics.
  • Only the read and write of the location designated by x are performed mutually atomically.
  • The evaluation of expr or expr-list, and the write to the location designated by v, do not need to be atomic with respect to the read or write of the location designated by x.

No task scheduling points occur between the read and the write of the location designated by x.

Any combination of two or more of these atomic constructs enforces mutually exclusive access to the locations designated by x.

A race condition exists when two unsynchronized threads access the same shared variable with at least one thread modifying the variable; this can cause unpredictable results. To avoid race conditions, all accesses of the locations designated by x that could potentially occur in parallel must be protected with an atomic construct.

Atomic regions do not guarantee exclusive access with respect to any accesses outside of atomic regions to the same storage location x even if those accesses occur during a critical or ordered region, while an OpenMP* lock is owned by the executing task, or during the execution of a reduction clause.

However, other OpenMP* synchronization can ensure the desired exclusive access. For example, a barrier pragma following a series of atomic updates to x guarantees that subsequent accesses do not form a race condition with the atomic accesses.

The use of the seq_cst clause forces the atomically performed operation to include an implicit flush operation for all variables. This causes the operation to have the same meaning as a memory_order_seq_cst atomic operation in C++11/C11.

Atomic operations without the seq_cst clause have the same meaning as a memory_order_relaxed atomic operation in C++11/C11.

Examples

The following examples demonstrate how to use this pragma.

Example: Atomic Update

#pragma omp atomic update
     k += n*mass;                // k is updated atomically

Example: Atomic Read

#pragma omp atomic read
     tmp = c;           //  c is read atomically

Example: Atomic Write

#pragma omp atomic write
     count = n*m;               // count is written atomically

Example: Atomic Capture

#pragma omp atomic capture
     { d = v; v += n; } // atomically update v, but capture original value of v in d
#pragma omp atomic capture
     { o = c++; }               // capture the old value of c, then increment c
 #pragma omp atomic capture seq_cst
     {--x; v = x;} // capture final value of x in v and flush all variables
For more complete information about compiler optimizations, see our Optimization Notice.