Skip to content

Commit c99ea30

Browse files
committed
Add weaker models (x86-TSO and ARM) to the "Memory consistency" section
1 parent 3833bb9 commit c99ea30

File tree

1 file changed

+83
-8
lines changed

1 file changed

+83
-8
lines changed

concurrency-primer.tex

Lines changed: 83 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,15 +1094,13 @@ \subsection{Memory consistency models}
10941094

10951095
When a program is compiled and executed, it doesn't always follow the written order. The system may change the sequence and optimize it to simulate line-by-line execution, as long as the final result matches the expected outcome.
10961096

1097-
This requires an agreement between the programmer and the system (hardware, compiler, etc.), ensuring that if the rules are followed, the execution will be correct. Correctness here means defining permissible outcomes among all possible results, known as Memory Consistency Models. These models allow the system to optimize while ensuring correct execution.
1097+
This requires an agreement between the programmer and the system (hardware, compiler, etc.), ensuring that if the rules are followed, the execution will be correct. Correctness here means defining permissible outcomes among all possible results, known as memory consistency models. These models allow the system to optimize while ensuring correct execution.
10981098

1099-
Memory Consistency Models operate at various levels. For example, when machine code runs on hardware, processors can reorder and optimize instructions, and the results must match expectations. Similarly, when converting high-level languages to assembly, compilers can rearrange instructions while ensuring consistent outcomes. Thus, from source code to hardware execution, agreements must ensure the expected results.
1100-
1101-
One can envision hardware that achieves sequential consistency as follows: each thread has direct access to shared memory, and memory processes only one read or write operation at a time. This naturally ensures sequential consistency.
1099+
Memory consistency models operate at various levels. For example, when machine code runs on hardware, processors can reorder and optimize instructions, and the results must match expectations. Similarly, when converting high-level languages to assembly, compilers can rearrange instructions while ensuring consistent outcomes. Thus, from source code to hardware execution, agreements must ensure the expected results.
11021100

11031101
\subsubsection{Sequential consistency (SC)}
11041102

1105-
In the 1970s, Leslie Lamport proposed the most common memory consistency model, Sequential Consistency (SC), defined as follows:
1103+
In the 1970s, Leslie Lamport proposed the most common memory consistency model, sequential consistency (SC), defined as follows:
11061104

11071105
\begin{quote}
11081106
A multiprocessor system is sequentially consistent if the result of any execution is the same as if the operations of all the processors were executed in some sequential order, and the operations of each individual processor appear in this sequence in the order specified by its program.
@@ -1117,6 +1115,7 @@ \subsubsection{Sequential consistency (SC)}
11171115
To enhance the understanding of sequential consistency, consider the following simple example. Two threads write to and read from two shared variables \monobox{x} and \monobox{y}, both initially set to \monobox{0}.
11181116

11191117
\begin{ccode}
1118+
// Litmus Test: Message Passing
11201119
int x = 0;
11211120
int y = 0;
11221121

@@ -1141,12 +1140,88 @@ \subsubsection{Sequential consistency (SC)}
11411140

11421141
Observing these orders, we see that none result in \monobox{r1 = 1} and \monobox{r2 = 0}. Thus, sequential consistency only allows the outcomes \monobox{(r1, r2)} to be \monobox{(1, 1)}, \monobox{(0, 1)}, and \monobox{(0, 0)}. With this convention, software can expect that \monobox{(1, 0)} will not occur, and hardware can optimize as long as it ensures the result \monobox{(1, 0)} does not appear.
11431142

1144-
We can imagine sequentially consistent hardware as the figure \ref{hw-seq-cst} shows: each thread can directly access shared memory, and memory processes one read or write operation at a time, naturally ensuring sequential consistency. In fact, there are multiple ways to implement sequentially consistent hardware. It can even include caches and be banked, as long as it ensures that the results behave the same as the aforementioned model.
1145-
1146-
\centering
1143+
\begin{center}
11471144
\includegraphics[keepaspectratio,width=0.7\linewidth]{images/hw-seq-cst}
11481145
\captionof{figure}{The memory model of sequentially consistent hardware.}
11491146
\label{hw-seq-cst}
1147+
\end{center}
1148+
1149+
We can imagine sequentially consistent hardware as the figure \ref{hw-seq-cst} shows: each thread can directly access shared memory, and memory processes one read or write operation at a time, naturally ensuring sequential consistency. In fact, there are multiple ways to implement sequentially consistent hardware. It can even include caches and be banked, as long as it ensures that the results behave the same as the aforementioned model.
1150+
1151+
\subsubsection{Total store order (TSO)}
1152+
1153+
Although sequential consistency is considered the "golden standard" for multi-threaded programs, its many constraints limit performance optimization. As a result, it is rarely implemented in modern processors. Instead, more relaxed memory models are used, such as the total store order (TSO) memory model adopted by the x86 architecture. One can envision the hardware roughly as follows:
1154+
1155+
\begin{center}
1156+
\includegraphics[keepaspectratio,width=0.7\linewidth]{images/hw-tso}
1157+
\captionof{figure}{The memory model of x86-TSO hardware.}
1158+
\label{hw-tso}
1159+
\end{center}
1160+
1161+
All processors can read from a single shared memory, but each processor writes only to its own write queue.
1162+
1163+
Consider the following Write Queue (Store Buffer) Litmus Test:
1164+
1165+
\begin{ccode}
1166+
// Litmus Test: Write Queue (Store Buffer)
1167+
int x = 0;
1168+
int y = 0;
1169+
1170+
// Thread 1 // Thread 2
1171+
x = 1; y = 1;
1172+
r1 = y; r2 = x;
1173+
\end{ccode}
1174+
1175+
Sequential consistency does not allow \monobox{r1 = r2 = 0}, but TSO does. In a sequentially consistent memory model, \monobox{x = 1} or \monobox{y = 1} must be written first, followed by the read operations, so \monobox{r1 = r2 = 0} cannot occur. However, under the TSO memory model, the write operations from both threads might still be in their respective queues when the read operations occur, allowing \monobox{r1 = r2 = 0}.
1176+
1177+
Non-sequentially consistent hardware typically supports additional memory barrier (fence) instructions to control the order of read and write operations. These barriers ensure that writes before the barrier are completed (queues emptied) before any subsequent reads are performed.
1178+
1179+
\begin{ccode}
1180+
// Thread 1 // Thread 2
1181+
x = 1; y = 1;
1182+
barrier; barrier;
1183+
r1 = y; r2 = x;
1184+
\end{ccode}
1185+
1186+
The reason total store order (TSO) is named as such is because once a write operation reaches shared memory, it indicates that all processors are aware that the value has been written. There will be no situation where different processors see different values. That is, the following litmus test will not have \monobox{r1 = 1}, \monobox{r2 = 0}, \monobox{r3 = 1}, but \monobox{r4 = 0}.
1187+
1188+
Consider the following Independent Reads of Independent Writes (IRIW) Litmus Test:
1189+
1190+
\begin{ccode}
1191+
// Litmus Test: Independent Reads of Independent Writes (IRIW)
1192+
int x = 0;
1193+
int y = 0;
1194+
1195+
// Thread 1 // Thread 2 // Thread 3 // Thread 4
1196+
x = 1; y = 1; r1 = x; r3 = y;
1197+
r2 = y; r4 = x;
1198+
\end{ccode}
1199+
1200+
Once Thread 3 reads \monobox{r1 = 1}, \monobox{r2 = 0}, it indicates that the write \monobox{x = 1} reached shared memory before \monobox{y = 1}. If at this point Thread 4 reads \monobox{r3 = 1}, it means both writes \monobox{y = 1} and \monobox{x = 1} are visible to Thread 4, so \monobox{r4} can only be \monobox{1}. We can say "Thread 1's write to \monobox{x}" happens before "Thread 2's write to \monobox{y}".
1201+
1202+
\subsubsection{Relaxed memory order (RMO)}
1203+
1204+
\begin{center}
1205+
\includegraphics[keepaspectratio,width=0.4\linewidth]{images/hw-relaxed}
1206+
\captionof{figure}{The memory model of \textsc{Arm} relaxed hardware.}
1207+
\label{hw-relaxed}
1208+
\end{center}
1209+
1210+
As shown in figure \ref{hw-relaxed}, the \textsc{Arm} instruction set adopts a more relaxed memory model. Each thread maintains its own copy of the memory, and every read and write operation targets this private copy. When writing to its own memory, it also propagates the changes to the memory of other threads. Thus, this model does not have a total store order. Furthermore, read operations can be delayed until they are actually needed.
1211+
1212+
The write order seen by one thread can differ from the order seen by other threads because write operations can be reordered during propagation. However, reads and writes to the same memory address must still follow a total order. Therefore, the following litmus test cannot result in \monobox{r1 = 1}, \monobox{r2 = 2}, but \monobox{r3 = 2}, \monobox{r4 = 1}. Which write overwrites which must be visible to all threads. This guarantee is known as coherence. Without coherence, programming for such a system would be very difficult.
1213+
1214+
All the litmus tests mentioned above are allowed under the relaxed memory model of \textsc{Arm}, except for the following example. Neither \textsc{Arm}, x86-TSO, nor sequential consistency model would result in \monobox{r1 = 1}, \monobox{r2 = 2}, \monobox{r3 = 2}, and \monobox{r4 = 1}.
1215+
1216+
\begin{ccode}
1217+
// Litmus Test: Coherence
1218+
int x = 0;
1219+
int y = 0;
1220+
1221+
// Thread 1 // Thread 2 // Thread 3 // Thread 4
1222+
x = 1; x = 2; r1 = x; r3 = x;
1223+
r2 = x; r4 = x;
1224+
\end{ccode}
11501225

11511226
\subsection{C11/C++11 atomics}
11521227

0 commit comments

Comments
 (0)