Summary
The atomic construct ensures that a specific storage location is accessed atomically, rather than exposing
it to the possibility of multiple, simultaneous reading and writing threads that may result in indeterminate
values.
Syntax
In the following syntax, atomic-clause is a clause that indicates the semantics for which atomicity is
enforced, and memory-order-clause is a clause that indicates the memory ordering behavior of the construct.
Specifically, atomic-clause is one of the following:
read write update
memory-order-clause is one of the following:
seq_cst acq_rel release acquire relaxed
and clause is either atomic-clause, memory-order-clause or one of the following:
x,
r (result),
and
v
(as
applicable)
are
lvalue
expressions
with
scalar
type.
e (expected)
is
an
expression
with
scalar
type,
in
forms
where
e
is
assigned
it
must
be
an
lvalue.
d (desired)
is
an
expression
with
scalar
type.
r
must
be
of
integral
type.
During
the
execution
of
an
atomic
region,
multiple
syntactic
occurrences
of
x
must
designate
the
same
storage
location.
None
of
v,
x,
r,
d
and
expr
(as
applicable)
may
access
the
storage
location
designated
by
any
other
in
the
list.
e
and
v
may
refer
to,
or
access,
the
same
storage
location.
expr
is
an
expression
with
scalar
type.
The
order
operation,
ordop,
is
one
of
<,
or
>.
binop
is
one
of
+,
*,
-,
/,
&,
^,
|,
<<,
or
>>.
binop,
binop=,
ordop,
==,
++,
and
--
are
not
overloaded
operators.
The
expression
xbinopexpr
must
be
numerically
equivalent
to
xbinop(expr).
This
requirement
is
satisfied
if
the
operators
in
expr
have
precedence
greater
than
binop,
or
by
using
parentheses
around
expr
or
subexpressions
of
expr.
The
expression
exprbinopx
must
be
numerically
equivalent
to
(expr)binopx.
This
requirement
is
satisfied
if
the
operators
in
expr
have
precedence
equal
to
or
greater
than
binop,
or
by
using
parentheses
around
expr
or
subexpressions
of
expr.
==
comparisons
are
performed
by
comparing
the
bits
that
comprise
each
object
as
with
memcmp.
For
forms
that
allow
multiple
occurrences
of
x,
the
number
of
times
that
x
is
evaluated
is
unspecified.
hint-expression
is
a
constant
integer
expression
that
evaluates
to
a
valid
synchronization
hint.
The syntax of the atomic construct takes any of the following forms:
or, if the capture clause is present and statement is preceded or followed by capture-statement,
statement can also have this form:
x=expr
If the compare clause is present then:
statement has one of these forms:
if(x==e)then x=d endif
if(x==e)x=d
or, if the capture clause is also present and statement is not preceded or followed by
capture-statement, statement has this form:
if(x==e)then x=d else v=x endif
In the preceding statements:
x,
v,
d
and
e
(as
applicable)
are
scalar
variables
of
intrinsic
type.
x
must
not
have
the
ALLOCATABLE
attribute.
During
the
execution
of
an
atomic
region,
multiple
syntactic
occurrences
of
x
must
designate
the
same
storage
location.
None
of
v,
expr,
and
expr-list
(as
applicable)
may
access
the
same
storage
location
as
x.
None
of
x,
expr,
and
expr-list
(as
applicable)
may
access
the
same
storage
location
as
v.
expr
is
a
scalar
expression.
expr-list
is
a
comma-separated,
non-empty
list
of
scalar
expressions.
If
intrinsic-procedure-name
refers
to
IAND,
IOR,
or
IEOR,
exactly
one
expression
must
appear
in
expr-list.
intrinsic-procedure-name
is
one
of
MAX,
MIN,
IAND,
IOR,
or
IEOR.
operator
is
one
of
+,
*,
-,
/,
.AND.,
.OR.,
.EQV.,
or
.NEQV..
The
expression
x
operator
expr
must
be
numerically
equivalent
to
x
operator
(expr).
This
requirement
is
satisfied
if
the
operators
in
expr
have
precedence
greater
than
operator,
or
by
using
parentheses
around
expr
or
subexpressions
of
expr.
The
expression
expr
operator
x
must
be
numerically
equivalent
to
(expr)
operator
x.
This
requirement
is
satisfied
if
the
operators
in
expr
have
precedence
equal
to
or
greater
than
operator,
or
by
using
parentheses
around
expr
or
subexpressions
of
expr.
intrinsic-procedure-name
must
refer
to
the
intrinsic
procedure
name
and
not
to
other
program
entities.
operator
must
refer
to
the
intrinsic
operator
and
not
to
a
user-defined
operator.
All
assignments
must
be
intrinsic
assignments.
For
forms
that
allow
multiple
occurrences
of
x,
the
number
of
times
that
x
is
evaluated
is
unspecified.
hint-expression
is
a
constant
expression
that
evaluates
to
a
scalar
value
with
kind
omp_sync_hint_kind
and
a
value
that
is
a
valid
synchronization
hint.
Binding
If the size of x is 8, 16, 32, or 64 bits and x is aligned to a multiple of its size, the binding thread set for the
atomic region is all threads on the device. Otherwise, the binding thread set for the atomic region is all
threads in the contention group. atomic regions enforce exclusive access with respect to other atomic
regions that access the same storage location x among all threads in the binding thread set without regard to
the teams to which the threads belong.
Description
If atomic-clause is not present on the construct, the behavior is as if the update clause is
specified.
The atomic construct with the read clause results in an atomic read of the location designated by
x.
The atomic construct with the write clause results in an atomic write of the location designated by
x.
The atomic construct with the update clause results in an atomic update of the location designated by x
using the designated operator or intrinsic. Only the read and write of the location designated by x are
performed mutually atomically. 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 are allowed between the read and the
write of the location designated by x.
If the capture clause is present, the atomic update is an atomic captured update — an atomic update to
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 original or final value of
the location designated by x is written in the location designated by v based on the base language semantics
of structured block or statements of the atomic construct. Only the read and write of the location
designated by x are performed mutually atomically. Neither the evaluation of expr or expr-list, nor the write
to the location designated by v, need be atomic with respect to the read or write of the location designated
by x.
If the compare clause is present, the atomic update is an atomic conditional update. For forms that use an
equality comparison, the operation is an atomic compare-and-swap — it atomically compares the value of x
to e and if they are equal writes the value of d into the location designated by x. Based on the base
language semantics of the associated structured block of the atomic construct, the original or
final value of the location designated by x is written to the location designated by v, which is
allowed to be the same location as designated by e, or the result of the comparison is written
to the location designated by r. Only the read and write of the location designated by x are
performed mutually atomically. Neither the evaluation of either e or d nor writes to the locations
designated by v and r need be atomic with respect to the read or write of the location designated by
x.
If the compare clause is present, forms that use ordop are logically an atomic maximum or minimum, but
they may be implemented with a compare-and-swap loop with short-circuiting. For forms where statement
is cond-expr-stmt, if the result of the condition implies that the value of x does not change then the update
may not occur.
If the weak clause is present, the comparison performed by an atomic compare-and-swap operation may
spuriously fail, evaluating to not equal even when the values are equal.
Note – Allowing for spurious failure by specifying a weak clause can result in performance gains on some
systems when using compare-and-swap in a loop. For cases where a single compare-and-swap would
otherwise be sufficient, using a loop over a weak compare-and-swap is unlikely to improve performance.
If memory-order-clause is present, or implicitly provided by a requires directive, it specifies the effective
memory ordering and otherwise the effective memory ordering is relaxed. If the fail clause is present,
its parameter overrides the effective memory ordering used if the comparison for an atomic conditional
update fails.
The atomic construct may be used to enforce memory consistency between threads, based on the
guarantees provided by Section 1.4.6. A strong flush on the location designated by x is performed
on entry to and exit from the atomic operation, ensuring that the set of all atomic operations
applied to the same location in a race-free program has a total completion order. If the write or
update clause is specified, the atomic operation is not an atomic conditional update for which the
comparison fails, and the effective memory ordering is release, acq_rel, or seq_cst, the
strong flush on entry to the atomic operation is also a release flush. If the read or update
clause is specified and the effective memory ordering is acquire, acq_rel, or seq_cst
then the strong flush on exit from the atomic operation is also an acquire flush. Therefore, if
the effective memory ordering is not relaxed, release and/or acquire flush operations are
implied and permit synchronization between the threads without the use of explicit flush
directives.
For all forms of the atomic construct, any combination of two or more of these atomic constructs
enforces mutually exclusive access to the locations designated by x among threads in the binding thread set.
To avoid data races, 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
that follows a series of atomic updates to x guarantees that subsequent accesses do not form a race with the
atomic accesses.
A compliant implementation may enforce exclusive access between atomic regions that update different
storage locations. The circumstances under which this occurs are implementation defined.
If the storage location designated by x is not size-aligned (that is, if the byte alignment of x is
not a multiple of the size of x), then the behavior of the atomic region is implementation
defined.
If present, the hint clause gives the implementation additional information about the expected properties
of the atomic operation that can optionally be used to optimize the implementation. The presence of a hint
clause does not affect the semantics of the atomic construct, and all hints may be ignored. If
no hint clause is specified, the effect is as if hint(omp_sync_hint_none) had been
specified.
Execution Model Events
The atomic-acquiring event occurs in the thread that encounters the atomic construct on entry to the
atomic region before initiating synchronization for the region.
The atomic-acquired event occurs in the thread that encounters the atomic construct after it enters the
region, but before it executes the structured block of the atomic region.
The atomic-released event occurs in the thread that encounters the atomic construct after it completes any
synchronization on exit from the atomic region.
Tool Callbacks
A thread dispatches a registered ompt_callback_mutex_acquire callback for each
occurrence of an atomic-acquiring event in that thread. This callback has the type signature
ompt_callback_mutex_acquire_t.
A thread dispatches a registered ompt_callback_mutex_acquired callback for each
occurrence of an atomic-acquired event in that thread. This callback has the type signature
ompt_callback_mutex_t.
A thread dispatches a registered ompt_callback_mutex_released callback with
ompt_mutex_atomic as the kind argument if practical, although a less specific kind may be
used, for each occurrence of an atomic-released event in that thread. This callback has the type
signature ompt_callback_mutex_t and occurs in the task that encounters the atomic
construct.
Restrictions
Restrictions to the atomic construct are as follows:
OpenMP
constructs
may
not
be
encountered
during
execution
of
an
atomic
region.
At
most
one
atomic-clause
may
appear
on
the
construct.
At
most
one
memory-order-clause
may
appear
on
the
construct.
At
most
one
hint
clause
may
appear
on
the
construct.
At
most
one
capture
clause
may
appear
on
the
construct.
At
most
one
compare
clause
may
appear
on
the
construct.
If
a
capture
or
compare
clause
appears
on
the
construct
then
atomic-clause
must
be
update.
At
most
one
fail
clause
may
appear
on
the
construct.
At
most
one
weak
clause
may
appear
on
the
construct.
If
atomic-clause
is
read
then
memory-order-clause
must
not
be
release.
If
atomic-clause
is
write
then
memory-order-clause
must
not
be
acquire.
The
weak
clause
may
only
appear
if
the
resulting
atomic
operation
is
an
atomic
conditional
update
for
which
the
comparison
tests
for
equality.
All
atomic
accesses
to
the
storage
locations
designated
by
x
throughout
the
program
are
required
to
have
a
compatible
type.
The
fail
clause
may
only
appear
if
the
resulting
atomic
operation
is
an
atomic
conditional
update.
All
atomic
accesses
to
the
storage
locations
designated
by
x
throughout
the
program
are
required
to
have
the
same
type
and
type
parameters.
The
fail
clause
may
only
appear
if
the
resulting
atomic
operation
is
an
atomic
conditional
update
or
an
atomic
update
where
intrinsic-procedure-name
is
either
MAX
or
MIN.