mirror of
https://github.com/OpenMP/Examples.git
synced 2025-04-03 13:21:33 +01:00
102 lines
5.6 KiB
TeX
102 lines
5.6 KiB
TeX
\cchapter{Synchronization}{synchronization}
|
|
\label{chap:synchronization}
|
|
|
|
The \kcode{barrier} construct is a stand-alone directive that requires all threads
|
|
of a team (within a contention group) to execute the barrier and complete
|
|
execution of all tasks within the region, before continuing past the barrier.
|
|
|
|
The \kcode{critical} construct is a directive that contains a structured block.
|
|
The construct allows only a single thread at a time to execute the structured block (region).
|
|
Multiple \kcode{critical} regions may exist in a parallel region, and may
|
|
act cooperatively (only one thread at a time in all \kcode{critical} regions),
|
|
or separately (only one thread at a time in each \kcode{critical} regions when
|
|
a unique name is supplied on each \kcode{critical} construct).
|
|
An optional (lock) \kcode{hint} clause may be specified on a named \kcode{critical}
|
|
construct to provide the OpenMP runtime guidance in selection a locking
|
|
mechanism.
|
|
|
|
On a finer scale the \kcode{atomic} construct allows only a single thread at
|
|
a time to have atomic access to a storage location involving a single read,
|
|
write, update or capture statement, and a limited number of combinations
|
|
when specifying the \kcode{capture} \plc{atomic-clause} clause. The
|
|
\plc{atomic-clause} clause is required for some expression statements, but is
|
|
not required for \kcode{update} statements. The \plc{memory-order} clause can be
|
|
used to specify the degree of memory ordering enforced by an \kcode{atomic}
|
|
construct. From weakest to strongest, they are \kcode{relaxed} (the default),
|
|
\plc{acquire} and/or \plc{release} clauses (specified with \kcode{acquire}, \kcode{release},
|
|
or \kcode{acq_rel}), and \kcode{seq_cst}. Please see the details in the
|
|
\docref{atomic Construct} subsection of the \docref{Directives} chapter in the OpenMP
|
|
Specifications document.
|
|
|
|
% The following three sentences were stolen from the spec.
|
|
The \kcode{ordered} construct either specifies a structured block in a loop,
|
|
simd, or loop SIMD region that will be executed in the order of the loop
|
|
iterations. The \kcode{ordered} construct sequentializes and orders the execution
|
|
of \kcode{ordered} regions while allowing code outside the region to run in parallel.
|
|
|
|
Since OpenMP 4.5 the \kcode{ordered} construct can also be a stand-alone
|
|
directive that specifies cross-iteration dependences in a \plc{doacross} loop nest.
|
|
The \kcode{depend} clause uses a \kcode{sink} \plc{dependence-type}, along with an
|
|
iteration vector argument (\plc{vec}) to indicate the iteration that satisfies the
|
|
dependence. The \kcode{depend} clause with a \kcode{source}
|
|
\plc{dependence-type} specifies dependence satisfaction.
|
|
|
|
The \kcode{flush} directive is a stand-alone construct for enforcing consistency
|
|
between a thread's view of memory and the view of memory for other threads (see
|
|
the Memory Model chapter of this document for more details). When the construct
|
|
is used with an explicit variable list, a \plc{strong flush} that forces a
|
|
thread's temporary view of memory to be consistent with the actual memory is
|
|
applied to all listed variables. When the construct is used without an explicit
|
|
variable list and without a \plc{memory-order} clause, a strong flush is
|
|
applied to all locally thread-visible data as defined by the base language, and
|
|
additionally the construct provides both acquire and release memory ordering
|
|
semantics. When an explicit variable list is not present and a
|
|
\plc{memory-order} clause is present, the construct provides acquire and/or
|
|
release memory ordering semantics according to the \plc{memory-order} clause,
|
|
but no strong flush is performed. A resulting strong flush that applies to a
|
|
set of variables effectively ensures that no memory (load or store)
|
|
operation for the affected variables may be reordered across the \kcode{flush}
|
|
directive.
|
|
|
|
General-purpose routines provide mutual exclusion semantics through locks,
|
|
represented by lock variables.
|
|
The semantics allows a task to \plc{set}, and hence
|
|
\plc{own} a lock, until it is \plc{unset} by the task that set it. A
|
|
\plc{nestable} lock can be set multiple times by a task, and is used
|
|
when in code requires nested control of locks. A \plc{simple lock} can
|
|
only be set once by the owning task. There are specific calls for the two
|
|
types of locks, and the variable of a specific lock type cannot be used by the
|
|
other lock type.
|
|
|
|
Any explicit task will observe the synchronization prescribed in a
|
|
\kcode{barrier} construct and an implied barrier. Also, additional synchronizations
|
|
are available for tasks. All children of a task will wait at a \kcode{taskwait} (for
|
|
their siblings to complete). A \kcode{taskgroup} construct creates a region in which the
|
|
current task is suspended at the end of the region until all sibling tasks,
|
|
and their descendants, have completed.
|
|
Scheduling constraints on task execution can be prescribed by the \kcode{depend}
|
|
clause to enforce dependence on previously generated tasks.
|
|
More details on controlling task executions can be found in the \docref{Tasking} Chapter
|
|
in the OpenMP Specifications document. %(DO REF. RIGHT.)
|
|
|
|
|
|
%===== Examples Sections =====
|
|
\input{synchronization/critical}
|
|
\input{synchronization/worksharing_critical}
|
|
\input{synchronization/barrier_regions}
|
|
\input{synchronization/atomic}
|
|
\input{synchronization/atomic_cas}
|
|
\input{synchronization/atomic_restrict}
|
|
\input{synchronization/atomic_hint}
|
|
\input{synchronization/acquire_release}
|
|
\input{synchronization/ordered}
|
|
\input{synchronization/depobj}
|
|
\input{synchronization/doacross}
|
|
\input{synchronization/locks}
|
|
\input{synchronization/init_lock}
|
|
\input{synchronization/init_lock_with_hint}
|
|
\input{synchronization/lock_owner}
|
|
\input{synchronization/simple_lock}
|
|
\input{synchronization/nestable_lock}
|
|
|