3.5A Little SC Formalism

book pp. 23–25 · ~2 min read

  • L(a)/S(a) notation
  • SC ordering rules
  • value rule
  • ordering table
  • safety vs. liveness

The notation

To compare SC with the weaker models of the next two chapters, we need it in a form we can manipulate. The book adopts the axiomatic formalism of Weaver and Germond (the SPARC manual — chapter 11 discusses axiomatic specification as a method):

  • L(a)L(a) and S(a)S(a) — a load and a store to address aa;
  • <p<_p program order : a per-core total order capturing the sequence in which that core logically executes memory operations;
  • <m<_m memory order : a total order on the memory operations of all cores.

SC in two rules

An SC execution requires:

(1) Program order is preserved — all cores insert their loads and stores into <m<_m respecting their program order, regardless of whether the addresses are the same or different (a=ba = b or aba \neq b). Four cases:

L(a)<pL(b)L(a)<mL(b)/* LoadLoad */L(a)<pS(b)L(a)<mS(b)/* LoadStore */S(a)<pS(b)S(a)<mS(b)/* StoreStore */S(a)<pL(b)S(a)<mL(b)/* StoreLoad */\begin{aligned} L(a) <_p L(b) &\Rightarrow L(a) <_m L(b) && \text{/* Load} \rightarrow \text{Load */} \\ L(a) <_p S(b) &\Rightarrow L(a) <_m S(b) && \text{/* Load} \rightarrow \text{Store */} \\ S(a) <_p S(b) &\Rightarrow S(a) <_m S(b) && \text{/* Store} \rightarrow \text{Store */} \\ S(a) <_p L(b) &\Rightarrow S(a) <_m L(b) && \text{/* Store} \rightarrow \text{Load */} \end{aligned}

(2) The value rule — every load gets its value from the last store before it in memory order to the same address:

val(L(a))=val(MAX<m{S(a)S(a)<mL(a)})\text{val}(L(a)) = \text{val}\big(\operatorname{MAX}_{<_m}\{\, S(a) \mid S(a) <_m L(a) \,\}\big)

where MAX<m\operatorname{MAX}_{<_m} denotes “latest in memory order.”

Atomic read-modify-write instructions (details in §3.9) add one more constraint: each RMW’s load and store must appear consecutively in <m<_m — no other memory operation, to any address, may interpose between the test and the set.

The ordering table

The book compresses rule (1) into a table — the template every later model will relax. An “X” means the program ordering (Operation 1 before Operation 2) is enforced:

Op 1 ↓ \ Op 2 →LoadStoreRMW
LoadXXX
StoreXXX
RMWXXX

X = ordering enforced · hover any cell

Table 3.4 (recreated): SC ordering rules — every entry is enforced.

Keep this table in mind as a baseline. In Chapter 4, TSO will erase exactly one X (Store→Load — the write-buffer relaxation you saw break Dekker in §3.1); Chapter 5’s relaxed models will erase nearly all of them and hand you a FENCE instruction to paint Xs back where you need them.

Safety and liveness

“An SC implementation permits only SC executions” — strictly speaking, that is the safety property (do no harm). Implementations also need liveness (do some good): a store must eventually become visible to a load repeatedly attempting to read that location — eventual write-propagation , typically ensured by the coherence protocol. (Without it, a machine that never propagated anything would be vacuously “SC.”) Starvation avoidance and fairness also matter but lie beyond this discussion.

Check yourself

1.SC's ordering rule (1) says op1 <p op2 implies op1 <m op2 for all four load/store cases. Does this apply when the two operations access the SAME address?

2.What does the value rule — val(L(a)) = val(MAX<m {S(a) | S(a) <m L(a)}) — say in plain English?

3.How does an atomic RMW (e.g., test-and-set) further constrain an SC execution?

4.The book notes SC implementations need a safety property and a liveness property. Which is which?

4 questions