|
2 | 2 | \chapter{Memory Model}
|
3 | 3 | \label{chap:memory_model}
|
4 | 4 |
|
5 |
| -In this chapter, examples illustrate race conditions on access to variables with |
6 |
| -shared data-sharing attributes. A race condition can exist when two |
7 |
| -or more threads are involved in accessing a variable in which not all |
8 |
| -of the accesses are reads; that is, a WaR, RaW or WaW condition |
9 |
| -exists (R=read, a=after, W=write). A RaR does not produce a race condition. |
10 |
| - Ensuring thread execution order at |
11 |
| -the processor level is not enough to avoid race conditions, because the |
12 |
| -local storage at the processor level (registers, caches, etc.) |
13 |
| -must be synchronized so that a consistent view of the variable in the |
14 |
| -memory hierarchy can be seen by the threads accessing the variable. |
| 5 | +OpenMP provides a shared-memory model that allows all threads on a given |
| 6 | +device shared access to \emph{memory}. For a given OpenMP region that may be |
| 7 | +executed by more than one thread or SIMD lane, variables in memory may be |
| 8 | +\emph{shared} or \emph{private} with respect to those threads or SIMD lanes. A |
| 9 | +variable's data-sharing attribute indicates whether it is shared (the |
| 10 | +\emph{shared} attribute) or private (the \emph{private}, \emph{firstprivate}, |
| 11 | +\emph{lastprivate}, \emph{linear}, and \emph{reduction} attributes) in the data |
| 12 | +environment of an OpenMP region. While private variables in an OpenMP region |
| 13 | +are new copies of the original variable (with same name) that may then be |
| 14 | +concurrently accessed or modified by their respective threads or SIMD lanes, a |
| 15 | +shared variable in an OpenMP region is the same as the variable of the same |
| 16 | +name in the enclosing region. Concurrent accesses or modifications to a |
| 17 | +shared variable may therefore require synchronization to avoid data races. |
15 | 18 |
|
16 |
| -OpenMP provides a shared-memory model which allows all threads access |
17 |
| -to \plc{memory} (shared data). Each thread also has exclusive |
18 |
| -access to \plc{threadprivate memory} (private data). A private |
19 |
| -variable referenced in an OpenMP directive's structured block is a |
20 |
| -new version of the original variable (with the same name) for each |
21 |
| -task (or SIMD lane) within the code block. A private variable is |
22 |
| -initially undefined (except for variables in \code{firstprivate} |
23 |
| -and \code{linear} clauses), and the original variable value is |
24 |
| -unaltered by assignments to the private variable, (except for |
25 |
| -\code{reduction}, \code{lastprivate} and \code{linear} clauses). |
| 19 | +OpenMP's memory model also includes a \emph{temporary view} of memory that is |
| 20 | +associated with each thread. Two different threads may see different values for |
| 21 | +a given variable in their respective temporary views. Threads may employ flush |
| 22 | +operations for the purposes of making their temporary view of a variable |
| 23 | +consistent with the value of the variable in memory. The effect of a given |
| 24 | +flush operation is characterized by its flush properties -- some combination of |
| 25 | +\emph{strong}, \emph{release}, and \emph{acquire} -- and, for \emph{strong} |
| 26 | +flushes, a \emph{flush-set}. |
26 | 27 |
|
27 |
| -Private variables in an outer \code{parallel} region can be |
28 |
| -shared by implicit tasks of an inner \code{parallel} region |
29 |
| -(with a \code{share} clause on the inner \code{parallel} directive). |
30 |
| -Likewise, a private variable may be shared in the region of an |
31 |
| -explicit \code{task} (through a \code{shared} clause). |
| 28 | +A \emph{strong} flush will force consistency between the temporary view and the |
| 29 | +memory for all variables in its \emph{flush-set}. Furthermore all strong flushes in a |
| 30 | +program that have intersecting flush-sets will execute in some total order, and |
| 31 | +within a thread strong flushes may not be reordered with respect to other |
| 32 | +memory operations on variables in its flush-set. \emph{Release} and |
| 33 | +\emph{acquire} flushes operate in pairs. A release flush may ``synchronize'' |
| 34 | +with an acquire flush, and when it does so the local memory operations that |
| 35 | +precede the release flush will appear to have been completed before the local |
| 36 | +memory operations on the same variables that follow the acquire flush. |
32 | 37 |
|
| 38 | +Flush operations arise from explicit \code{flush} directives, implicit |
| 39 | +\code{flush} directives, and also from the execution of \code{atomic} |
| 40 | +constructs. The \code{flush} directive forces a consistent view of local |
| 41 | +variables of the thread executing the \code{flush}. When a list is supplied on |
| 42 | +the directive, only the items (variables) in the list are guaranteed to be |
| 43 | +flushed. Implied flushes exist at prescribed locations of certain constructs. |
| 44 | +For the complete list of these locations and associated constructs, please |
| 45 | +refer to the \plc{flush Construct} section of the OpenMP Specifications |
| 46 | +document. |
| 47 | + |
| 48 | +In this chapter, examples illustrate how race conditions may arise for accesses |
| 49 | +to variables with a \plc{shared} data-sharing attribute when flush operations |
| 50 | +are not properly employed. A race condition can exist when two or more threads |
| 51 | +are involved in accessing a variable in which not all of the accesses are |
| 52 | +reads; that is, a WaR, RaW or WaW condition exists (R=read, a=after, W=write). |
| 53 | +A RaR does not produce a race condition. In particular, a data race will arise |
| 54 | +when conflicting accesses do not have a well-defined \emph{completion order}. |
| 55 | +The existence of data races in OpenMP programs result in undefined behavior, |
| 56 | +and so they should generally be avoided for programs to be correct. The |
| 57 | +completion order of accesses to a shared variable is guaranteed in OpenMP |
| 58 | +through a set of memory consistency rules that are described in the \plc{OpenMP |
| 59 | +Memory Consitency} section of the OpenMP Specifications document. |
| 60 | + |
| 61 | +%This chapter also includes examples that exhibit non-sequentially consistent |
| 62 | +%(\emph{non-SC}) behavior. Sequential consistency (\emph{SC}) is the desirable |
| 63 | +%property that the results of a multi-threaded program are as if all operations |
| 64 | +%are performed in some total order, consistent with the program order of |
| 65 | +%operations performed by each thread. OpenMP guarantees that a correct program |
| 66 | +%(i.e. a program that does not have a data race) will exhibit SC behavior |
| 67 | +%so long as the only \code{atomic} constructs it uses are SC atomic directives. |
33 | 68 |
|
34 |
| -The \code{flush} directive forces a consistent view of local variables |
35 |
| -of the thread executing the \code{flush}. |
36 |
| -When a list is supplied on the directive, only the items (variables) |
37 |
| -in the list are guaranteed to be flushed. |
38 | 69 |
|
39 |
| -Implied flushes exist at prescribed locations of certain constructs. |
40 |
| -For the complete list of these locations and associated constructs, |
41 |
| -please refer to the \plc{flush Construct} section of the OpenMP |
42 |
| -Specifications document. |
43 | 70 |
|
44 | 71 | % The following table lists construct in which implied flushes exist, and the
|
45 | 72 | % location of their execution.
|
@@ -102,4 +129,4 @@ \chapter{Memory Model}
|
102 | 129 | % specific storage location accessed atomically (specified as the \plc{x} variable
|
103 | 130 | % in \plc{atomic Construct} subsection of the OpenMP Specifications document).
|
104 | 131 |
|
105 |
| -Examples 1-3 show the difficulty of synchronizing threads through \code{flush} and \code{atomic} directives. |
| 132 | +% Examples 1-3 show the difficulty of synchronizing threads through \code{flush} and \code{atomic} directives. |
0 commit comments