Weak memory models using event structures Simon Castellan1 1 LIP,
ENS Lyon
June 13th, 2017 Journées GPL
Unexpected behaviours
A simple concurrent and imperative program: x, y initialised to 0 y := 2 x:= 1 r ←y s←x shared variable · local register Expected outcome: r 6= 0 ∨ s 6= 0.
Weak memory models using event structures · Simon Castellan
2 / 26
Unexpected behaviours
A simple concurrent and imperative program: x, y initialised to 0 r ←y s←x x:= 1 y := 2 shared variable · local register Expected outcome: r 6= 0 ∨ s 6= 0. Wrong on modern architectures (x86, ARM, . . . ).
Weak memory models using event structures · Simon Castellan
2 / 26
A need to specify the behaviour Expected behaviour of a concurrent program? → architecture-dependent. Architectures need to be specified: I reorderings? I write propagation?
Weak memory models using event structures · Simon Castellan
3 / 26
A need to specify the behaviour Expected behaviour of a concurrent program? → architecture-dependent. Architectures need to be specified: I reorderings? I write propagation? To that end, manufacturers provide prosaic documents, but: I ambiguities: behaviours that are not specified I inconsistencies: some observations may not be predicted. Some architectures: I SC (Sequential consistency): no reordering, sequential memory, I ARM: reordering of instructions targeting different variables, write caches. I x86: . . . Weak memory models using event structures · Simon Castellan
3 / 26
Semantics saves the day Semantics: Formalise mathematically the vendors specifications: I
get a (possibly computer-verified) proof of non-ambiguity,
I
implement the specifications and mechanically test it against real life architectures.
Two main types of semantics among existing models: I
operational semantics: executions are runs of an abstract machine,
I
axiomatic semantics: axiomatized valid executions.
Those models are called weak memory models.
Weak memory models using event structures · Simon Castellan
4 / 26
A simple weak memory model: TSO This talk focuses a simple weak memory model: TSO. Store buffering. (can observe r = s = 0 on TSO but not SC): x, y initialised to 0 y := 1 x:= 1 r ←y s←x
Weak memory models using event structures · Simon Castellan
5 / 26
A simple weak memory model: TSO This talk focuses a simple weak memory model: TSO. Store buffering. (can observe r = s = 0 on TSO but not SC): x, y initialised to 0 y := 1 x:= 1 r ←y s←x Implemented by thread-local write buffers. ht1 k . . . k tn @(µ : V → N)i | {z } becomes
ht1 : |
States of a SC machine κ1 ∈ (V × N)∗ k . . .
{z
k tn : κn @µi }
State of a TSO machine
Weak memory models using event structures · Simon Castellan
5 / 26
A simple weak memory model: TSO This talk focuses a simple weak memory model: TSO. Store buffering. (can observe r = s = 0 on TSO but not SC): x, y initialised to 0 y := 1 x:= 1 r ←y s←x Implemented by thread-local write buffers. ht1 k . . . k tn @(µ : V → N)i | {z } becomes
ht1 : |
States of a SC machine κ1 ∈ (V × N)∗ k . . .
{z
k tn : κn @µi }
State of a TSO machine
Some transition rules: (Write)
h(x:= k; t : b)@µi → h(t : b++[(x, k)])@µi
(Commit) h(t : [(x, k)]++b)@µi → h(t : b)@µ[x ← k]i Weak memory models using event structures · Simon Castellan
5 / 26
Barriers in TSO TSO provides an instruction to forbid these behaviours: mfence. x, y initialised to 0 x:= 1 y := 1 mfence mfence s←x r ←y Outcome r = 0 ∧ s = 0 becomes forbidden. Transition (forces buffers to be emptied beforehand via (Commit)): (Fence) h(mfence; t : [])@µi → h(t : [])@µi
Weak memory models using event structures · Simon Castellan
6 / 26
This talk A semantics that is I denotational: executions computed by induction I
I
compact: based on event structures I
I
the semantics is thus compositional
no combinatorial explosion
extensible: inspired from game semantics I
it is easy to add loops, control operators, higher-order, . . .
Outline of the talk: 1. A semantics warm-up: compute the SC semantics using traces. 2. Getting back the causality. 3. An example: a model for TSO. Weak memory models using event structures · Simon Castellan
7 / 26
I. A denotational semantics for SC With traces of originality
Weak memory models using event structures · Simon Castellan
8 / 26
Syntax precedes semantics Our very simple programming language: e, e 0 ::=
{ Expressions } k ∈ N | r ∈ R | e + e0
ι ::=
{ Instructions }
| a := e
(Write on a variable)
|r ← a
(Read on a variable)
| mfence t ::=
(Barrier)
{ Threads }
| ι; . . . ; ι p ::=
{ Programs } t1 k . . . k tn
In real life: conditionals, loops, . . . Weak memory models using event structures · Simon Castellan
9 / 26
Denotational semantics Goal: compute JtK ∈ E where E is some space of denotations. Our space here: langages of traces. Σc = Wx:=k | Rx=k
(External memory event)
Σi = mfence | Σc
(Internal memory event)
∗
E = P(Σc )
Two steps: 1. Thread semantics T JtK: shared variables are considered volatile: T Jx:= 1; r ← xK does not guarantee to read 1 in r .
2. Closed semantics: once T JtK is calculated for the whole program, we restrict the scope of the variable Jx:= 1; r ← xK reads 1 in r . Weak memory models using event structures · Simon Castellan
10 / 26
Thread semantics Semantics of threads. Parametrized over ρ : R → N: (Fences) T Jmfence; tK(ρ) = T JtKρ (Writes)
(Reads)
T Jx:= e; tK(ρ) = Wx:=ρ(e) · T JtKρ [ T Jr ← x; tK(ρ) = Rx=i · T JtK(ρ[r ← i]) i∈N
Weak memory models using event structures · Simon Castellan
11 / 26
Thread semantics Semantics of threads. Parametrized over ρ : R → N: (Fences) T Jmfence; tK(ρ) = T JtKρ (Writes)
(Reads)
T Jx:= e; tK(ρ) = Wx:=ρ(e) · T JtKρ [ T Jr ← x; tK(ρ) = Rx=i · T JtK(ρ[r ← i]) i∈N
Semantics of programs. Obtained by interleaving (~): T Jt1 k . . . k tn K = T Jt1 K(∅) ~ . . . ~ T Jtn K(∅)
Weak memory models using event structures · Simon Castellan
11 / 26
Thread semantics Semantics of threads. Parametrized over ρ : R → N: (Fences) T Jmfence; tK(ρ) = T JtKρ (Writes)
(Reads)
T Jx:= e; tK(ρ) = Wx:=ρ(e) · T JtKρ [ T Jr ← x; tK(ρ) = Rx=i · T JtK(ρ[r ← i]) i∈N
Semantics of programs. Obtained by interleaving (~): T Jt1 k . . . k tn K = T Jt1 K(∅) ~ . . . ~ T Jtn K(∅) Example. Define p = (x:= 1; y ← r k y := 1; x ← s) I I
Wx:=1 · Wy :=1 · Ry =3 · Rx=2 ∈ JpK
but Rx=0 · Ry =0 · Wx:=1 · Wy :=1 6∈ JpK. Weak memory models using event structures · Simon Castellan
11 / 26
Closed semantics Obtained by eliminating “inconsistent” traces (eg. Wx:=2 · Rx=3 ) Linear memory model. A language of “consistent” traces: M(µ : V → N) ::= | τ : Rx=µ(x) · M(µ) | τ : Wx:=k · M(µ[x ← k]) M ::= M(x 7→ 0) Closed semantics: JpK = T JpK ∩ M. Example. Write p = (x:= 1; r ← y ) k (y := 2; s ← x) I
every trace of JpK ends with Rx=1 or a Ry =2 . Weak memory models using event structures · Simon Castellan
12 / 26
Summary Advantages. I
Easy to define semantics, by induction on programs.
I
By changing M, complex cache schemes can be handled
Drawbacks. I
Combinatorial explosion due to interleavings.
I
How to model reordering of instructions?
Towards partial-orders. I
Because of reorderings, threads are not totally ordered
I
Our goal: compute fine precisely dependencies between the instructions, given an architecture.
Weak memory models using event structures · Simon Castellan
13 / 26
II. Event structures Raiders of the lost causality
Weak memory models using event structures · Simon Castellan
14 / 26
Replacing traces by partial-orders Idea: thread semantics should be a set of partial-orders. Term: x:= 1; y := 1; r ← x; s ← y ; z:= s + t
Weak memory models using event structures · Simon Castellan
15 / 26
Replacing traces by partial-orders Idea: thread semantics should be a set of partial-orders. Dependencies (depends on the architecture): x:= 1
y := 1
r ←x
s←y z:= r + s
Weak memory models using event structures · Simon Castellan
15 / 26
Replacing traces by partial-orders Idea: thread semantics should be a set of partial-orders. Executions (depends on the architecture): Wx:=1
Wy :=1
Rx=i
Ry =j Wz:=i+j for i, j ∈ N2 .
I
traces on Σc becomes partially ordered multisets over Σc (pomsets)
I
T JtK becomes a set of such pomsets. Weak memory models using event structures · Simon Castellan
15 / 26
Replacing traces by partial-orders Idea: thread semantics should be a set of partial-orders. Executions (depends on the architecture): Wx:=1
Wy :=1
Rx=i
Ry =j Wz:=i+j for i, j ∈ N2 .
I
traces on Σc becomes partially ordered multisets over Σc (pomsets)
I
T JtK becomes a set of such pomsets.
I
Problem: lots of redundancies in the pomsets.. Weak memory models using event structures · Simon Castellan
15 / 26
Can we sum up all executions in a single object? Can we glue the executions all together in a partial-order? For instance: Wx:=1 Wy :=1 Rx=0
Rx=1
···
Wz:=0
Wz:=1
Wz:=2
Ry =0
Ry =1
Wz:=1
···
···
Which sets of events are (partial) executions? I
downward-closed for _
Weak memory models using event structures · Simon Castellan
16 / 26
Can we sum up all executions in a single object? Can we glue the executions all together in a partial-order? For instance: Wx:=1 Wy :=1 Rx=0
Rx=1
···
Wz:=0
Wz:=1
Wz:=2
Ry =0
Ry =1
Wz:=1
···
···
Which sets of events are (partial) executions? I I
downward-closed for _
and . . . ? {Wx:=1 , Rx=0 , Rx=1 } cannot be a valid execution.
Weak memory models using event structures · Simon Castellan
16 / 26
Can we sum up all executions in a single object? Can we glue the executions all together in a partial-order? For instance: Wx:=1 Wy :=1 Rx=0
Rx=1
···
Wz:=0
Wz:=1
Wz:=2
Ry =0
Ry =1
Wz:=1
···
···
Which sets of events are (partial) executions? I I
downward-closed for _
and . . . ? {Wx:=1 , Rx=0 , Rx=1 } cannot be a valid execution.
⇒ Need more structure than a partial-order: conflicts. Weak memory models using event structures · Simon Castellan
16 / 26
Event structures save the day Definition (Event structures) A set of event E with: I
A notion of causality represented by a partial order ≤E
I
A notion of conflict represented by a relation
I
A labelling l : E → Σ.
E
such that: I
the downclosure of a singleton set is finite
I
if e
E
e 0 , there is no e 00 above e and e 0
Definition (Configuration or partial execution) A configuration of E is a subset w of E : I
downward-closed: e ≤ e 0 ∈ w ⇒ e ∈ w .
I
that does not contain two conflicting events Weak memory models using event structures · Simon Castellan
17 / 26
Event structures save the day On the example: Wx:=1 Rx=0
Wy :=1
Rx=1
···
Wz:=0
Wz:=1
Wz:=2
Ry =0
Ry =1
Wz:=1
···
Weak memory models using event structures · Simon Castellan
···
18 / 26
Event structures save the day On the example: Wx:=1 Rx=0
Wy :=1
Rx=1
···
Wz:=0
Wz:=1
Wz:=2
Ry =0
Ry =1
Wz:=1
···
···
We have the configuration: Wx:=1
Weak memory models using event structures · Simon Castellan
18 / 26
Event structures save the day On the example: Wx:=1 Rx=0
Wy :=1
Rx=1
···
Wz:=0
Wz:=1
Wz:=2
Ry =0
Ry =1
Wz:=1
···
···
We have the configuration: Wx:=1 Rx=1
Weak memory models using event structures · Simon Castellan
18 / 26
Event structures save the day On the example: Wx:=1 Rx=0
Wy :=1
Rx=1
···
Wz:=0
Wz:=1
Wz:=2
Ry =0
Ry =1
Wz:=1
···
···
We have the configuration: Wx:=1
Wy :=1
Rx=1
Weak memory models using event structures · Simon Castellan
18 / 26
Event structures save the day On the example: Wx:=1 Rx=0
Wy :=1
Rx=1
···
Wz:=0
Wz:=1
Wz:=2
Ry =0
Ry =1
Wz:=1
···
···
We have the configuration: Wx:=1
Wy :=1
Rx=1
Ry =1
Weak memory models using event structures · Simon Castellan
18 / 26
Event structures save the day On the example: Wx:=1 Rx=0
Wy :=1
Rx=1
···
Wz:=0
Wz:=1
Wz:=2
Ry =0
Ry =1
Wz:=1
···
···
We have the configuration: Wx:=1
Wy :=1
Rx=1
Ry =1 Wz:=2
Weak memory models using event structures · Simon Castellan
18 / 26
III. Designing a semantics with event structures Dessine-moi une structure d’événements
Weak memory models using event structures · Simon Castellan
19 / 26
A model for the TSO architecture We now repeat the story using event structures for TSO. Two steps: I Thread semantics: T JtK is an event structure I Closed semantics: JtK = T JtK ∧ M Store buffering: x, y initialized to 0 x:= 1 y := 1 r ←y s←x becomes: Rx=0
Wx:=1
Ry =0
Wy :=1
Wx:=1
Rx=1
Wy :=1
Ry =1
Notice: syntactic dependencies are lost. (reorderings) Weak memory models using event structures · Simon Castellan
20 / 26
Thread semantics: Fences and reads By induction as before, generalizing operations to event structures.
T Jmfence; tKρ = mfence · JtKρ mfence JtKρ T Jr ← x; tKρ =
X i∈N
Rx=i · JtK (ρ[r ← i]) Rx=0
Rx=1
...
JtK (ρ[r ← 0])
JtK (ρ[r ← 1])
...
Weak memory models using event structures · Simon Castellan
21 / 26
Thread semantics: writes and programs Reorderings. Given x, Σ decomposes in: Σ = {Ry =k | y 6= x} | {z } =Ix
∪
{mfence, Rx=k , Wy :=k | k ∈ N} | {z } =Cx
Semantics of writes. T Jx:= e; tK(ρ) = Wx:=ρ(e) ·Cx JtK(ρ) Wx:=ρ(e) i1 c1
i2 .. .
c2
Semantics of programs. T Jt1 k . . . k tn K = T Jt1 K(_ 7→ 0) k . . . k T Jtn K(_ 7→ 0) Weak memory models using event structures · Simon Castellan
22 / 26
Examples I
x:= 1; r ← y gives Wx:=1
Ry =0
Ry =1
...
Weak memory models using event structures · Simon Castellan
23 / 26
Examples I
x:= 1; r ← y gives Wx:=1
I
Ry =0
Ry =1
...
x:= 1; r ← y k y := 1; s ← x gives Wx:=1
Ry =0
Ry =1
...
Wy :=1
Rx=0
Weak memory models using event structures · Simon Castellan
Rx=1
...
23 / 26
Examples I
x:= 1; r ← y gives Wx:=1
I
Ry =1
...
x:= 1; r ← y k y := 1; s ← x gives Wx:=1
I
Ry =0
Ry =0
...
Ry =1
Wy :=1
Rx=0
Rx=1
...
x:= 1; r ← x; s ← y gives Wx:=1 Rx=0 Ry =0
Rx=1 Ry =1
Ry =0
Ry =1
How to represent storage semantics? Weak memory models using event structures · Simon Castellan
23 / 26
Consistent memory behaviours From consistent traces, we go to consistent partial orders.
Weak memory models using event structures · Simon Castellan
24 / 26
Consistent memory behaviours From consistent traces, we go to consistent partial orders. A Σ-labelled partial order q is consistent when it satisfies: 1. Coherent reading. For e = Rx=k ∈ q, {Wx:=n ∈ q | Wx:=n ≤ e} has a maximal event Wx:=k Wy :=2 Wx:=2
Wx:=3
Ry =0
Rx=3
2. Per-variable serialization. A write and a read on the same variable in q are comparable Wx:=1
Wx:=4 Rx=1
Wy :=2
Wx:=0
Weak memory models using event structures · Simon Castellan
24 / 26
M and the synchronized product Theorem There exists an event structure M whose configurations are exactly consistent executions. (Relies on executions being closed under “prefix”) How to combine T JtK and M ? Using the synchronized product: JtK = T JtK ∧ M .
(generalizes intersection of sets of traces)
Traces of JtK correspond to those generated the operational machine.
Weak memory models using event structures · Simon Castellan
25 / 26
Conclusion Summary. I
We defined an denotational and extensible interpretation of concurrent programs in terms of event structures.
I
The model can be phrased in terms of game semantics which allows to present reorderings more abstractly, and interpret more complicated features (eg. higher-order)
To go further. I
Look at models for weaker archtectures (eg. POWER/ARM)
I
Software models? (the model is very expressive)
Weak memory models using event structures · Simon Castellan
26 / 26