Download presentation
Presentation is loading. Please wait.
1
Concurrent Objects Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit Modified by Rajeev Alur for CIS 640, University of Pennsylvania
2
Art of Multiprocessor Programming 2 Concurrent Computation memory object
3
Art of Multiprocessor Programming 3 Objectivism What is a concurrent object? –How do we describe one? –How do we implement one? –How do we tell if we ’ re right?
4
Art of Multiprocessor Programming 4 Objectivism What is a concurrent object? –How do we describe one? –How do we tell if we ’ re right?
5
Art of Multiprocessor Programming 5 FIFO Queue: Enqueue Method q.enq ( )
6
Art of Multiprocessor Programming 6 FIFO Queue: Dequeue Method q.deq()/
7
Art of Multiprocessor Programming 7 A Lock-Based Queue class LockBasedQueue { int head, tail; T[] items; Lock lock; public LockBasedQueue(int capacity) { head = 0; tail = 0; lock = new ReentrantLock(); items = (T[]) new Object[capacity]; }
8
Art of Multiprocessor Programming 8 A Lock-Based Queue class LockBasedQueue { int head, tail; T[] items; Lock lock; public LockBasedQueue(int capacity) { head = 0; tail = 0; lock = new ReentrantLock(); items = (T[]) new Object[capacity]; } 0 1 capacity-1 2 head tail y z Queue fields protected by single shared lock
9
Art of Multiprocessor Programming 9 A Lock-Based Queue class LockBasedQueue { int head, tail; T[] items; Lock lock; public LockBasedQueue(int capacity) { head = 0; tail = 0; lock = new ReentrantLock(); items = (T[]) new Object[capacity]; } 0 1 capacity-1 2 head tail y z Initially head = tail
10
Art of Multiprocessor Programming 10 Implementation: Deq public T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } 0 1 capacity-1 2 head tail y z
11
Art of Multiprocessor Programming 11 Implementation: Deq public T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } Method calls mutually exclusive 0 1 capacity-1 2 head tail y z
12
Art of Multiprocessor Programming 12 Implementation: Deq public T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } If queue empty throw exception 0 1 capacity-1 2 head tail y z
13
Art of Multiprocessor Programming 13 Implementation: Deq public T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } Queue not empty: remove item and update head 0 1 capacity-1 2 head tail y z
14
Art of Multiprocessor Programming 14 Implementation: Deq public T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } Return result 0 1 capacity-1 2 head tail y z
15
Art of Multiprocessor Programming 15 Implementation: Deq public T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } Release lock no matter what! 0 1 capacity-1 2 head tail y z
16
Art of Multiprocessor Programming 16 Implementation: Deq public T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } Should be correct because modifications are mutually exclusive…
17
Art of Multiprocessor Programming 17 Now consider the following implementation The same thing without mutual exclusion For simplicity, only two threads –One thread enq only –The other deq only
18
Art of Multiprocessor Programming 18 Wait-free 2-Thread Queue public class WaitFreeQueue { int head = 0, tail = 0; items = (T[]) new Object[capacity]; public void enq(Item x) { while (tail-head == capacity); // busy-wait items[tail % capacity] = x; tail++; } public Item deq() { while (tail == head); // busy-wait Item item = items[head % capacity]; head++; return item; }}
19
Art of Multiprocessor Programming 19 Wait-free 2-Thread Queue public class LockFreeQueue { int head = 0, tail = 0; items = (T[]) new Object[capacity]; public void enq(Item x) { while (tail-head == capacity); // busy-wait items[tail % capacity] = x; tail++; } public Item deq() { while (tail == head); // busy-wait Item item = items[head % capacity]; head++; return item; }} 0 1 capacity-1 2 head tail y z
20
Art of Multiprocessor Programming 20 Lock-free 2-Thread Queue public class LockFreeQueue { int head = 0, tail = 0; items = (T[])new Object[capacity]; public void enq(Item x) { while (tail-head == capacity); // busy-wait items[tail % capacity] = x; tail++; } public Item deq() { while (tail == head); // busy-wait Item item = items[head % capacity]; head++; return item; }} 0 1 capacity-1 2 head tail y z Queue is updated without a lock! How do we define “correct” when modifications are not mutually exclusive?
21
Art of Multiprocessor Programming 21 Defining concurrent queue implementations Need a way to specify a concurrent queue object Need a way to prove that an algorithm implements the object ’ s specification Lets talk about object specifications …
22
Correctness and Progress In a concurrent setting, we need to specify both the safety and the liveness properties of an object Need a way to define –when an implementation is correct –the conditions under which it guarantees progress Art of Multiprocessor Programming 22 Lets begin with correctness
23
Art of Multiprocessor Programming 23 Sequential Objects Each object has a state –Usually given by a set of fields –Queue example: sequence of items Each object has a set of methods –Only way to manipulate state –Queue example: enq and deq methods
24
Art of Multiprocessor Programming 24 Sequential Specifications If (precondition) –the object is in such-and-such a state –before you call the method, Then (postcondition) –the method will return a particular value –or throw a particular exception. and (postcondition, con ’ t) –the object will be in some other state –when the method returns,
25
Art of Multiprocessor Programming 25 Pre and PostConditions for Dequeue Precondition: –Queue is non-empty Postcondition: –Returns first item in queue Postcondition: –Removes first item in queue
26
Art of Multiprocessor Programming 26 Pre and PostConditions for Dequeue Precondition: –Queue is empty Postcondition: –Throws Empty exception Postcondition: –Queue state unchanged
27
Art of Multiprocessor Programming 27 Why Sequential Specifications Totally Rock Interactions among methods captured by side-effects on object state –State meaningful between method calls Documentation size linear in number of methods –Each method described in isolation Can add new methods –Without changing descriptions of old methods
28
Art of Multiprocessor Programming 28 What About Concurrent Specifications ? Methods? Documentation? Adding new methods?
29
Art of Multiprocessor Programming 29 Methods Take Time time
30
Art of Multiprocessor Programming 30 Methods Take Time time invocation 12:00 q.enq(... ) time
31
Art of Multiprocessor Programming 31 Methods Take Time time Method call invocation 12:00 q.enq(... ) time
32
Art of Multiprocessor Programming 32 Methods Take Time time Method call invocation 12:00 q.enq(... ) time
33
Art of Multiprocessor Programming 33 Methods Take Time time Method call invocation 12:00 q.enq(... ) time void response 12:01
34
Art of Multiprocessor Programming 34 Sequential vs Concurrent Sequential –Methods take time? Who knew? Concurrent –Method call is not an event –Method call is an interval.
35
Art of Multiprocessor Programming 35 time Concurrent Methods Take Overlapping Time time
36
Art of Multiprocessor Programming 36 time Concurrent Methods Take Overlapping Time time Method call
37
Art of Multiprocessor Programming 37 time Concurrent Methods Take Overlapping Time time Method call
38
Art of Multiprocessor Programming 38 time Concurrent Methods Take Overlapping Time time Method call
39
Art of Multiprocessor Programming 39 Sequential vs Concurrent Sequential: –Object needs meaningful state only between method calls Concurrent –Because method calls overlap, object might never be between method calls
40
Art of Multiprocessor Programming 40 Sequential vs Concurrent Sequential: –Each method described in isolation Concurrent –Must characterize all possible interactions with concurrent calls What if two enq s overlap? Two deq s? enq and deq ? …
41
Art of Multiprocessor Programming 41 Sequential vs Concurrent Sequential: –Can add new methods without affecting older methods Concurrent: –Everything can potentially interact with everything else
42
Art of Multiprocessor Programming 42 Sequential vs Concurrent Sequential: –Can add new methods without affecting older methods Concurrent: –Everything can potentially interact with everything else Panic!
43
Art of Multiprocessor Programming 43 The Big Question What does it mean for a concurrent object to be correct? –What is a concurrent FIFO queue? –FIFO means strict temporal order –Concurrent means ambiguous temporal order
44
Art of Multiprocessor Programming 44 Intuitively… public T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); }
45
Art of Multiprocessor Programming 45 Intuitively… public T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } All modifications of queue are done mutually exclusive
46
Art of Multiprocessor Programming 46 time Intuitively q.deq q.enq enq deq lock() unlock() lock() unlock() Behavior is “Sequential” enq deq Lets capture the idea of describing the concurrent via the sequential
47
Art of Multiprocessor Programming 47 Linearizability Each method should –“ take effect ” –Instantaneously –Between invocation and response events Object is correct if this “ sequential ” behavior is correct Any such concurrent object is –Linearizable ™
48
Art of Multiprocessor Programming 48 Is it really about the object? Each method should –“ take effect ” –Instantaneously –Between invocation and response events Sounds like a property of an execution … A linearizable object: one all of whose possible executions are linearizable
49
Art of Multiprocessor Programming 49 Example time (6)
50
Art of Multiprocessor Programming 50 Example time q.enq(x) time (6)
51
Art of Multiprocessor Programming 51 Example time q.enq(x) q.enq(y) time (6)
52
Art of Multiprocessor Programming 52 Example time q.enq(x) q.enq(y)q.deq(x) time (6)
53
Art of Multiprocessor Programming 53 Example time q.enq(x) q.enq(y)q.deq(x) q.deq(y) time (6)
54
Art of Multiprocessor Programming 54 Example time q.enq(x) q.enq(y)q.deq(x) q.deq(y) linearizable q.enq(x) q.enq(y)q.deq(x) q.deq(y) time (6)
55
Art of Multiprocessor Programming 55 Example time q.enq(x) q.enq(y)q.deq(x) q.deq(y) Valid? q.enq(x) q.enq(y)q.deq(x) q.deq(y) time (6)
56
Art of Multiprocessor Programming 56 Example time (5)
57
Art of Multiprocessor Programming 57 Example time q.enq(x) (5)
58
Art of Multiprocessor Programming 58 Example time q.enq(x)q.deq(y) (5)
59
Art of Multiprocessor Programming 59 Example time q.enq(x) q.enq(y) q.deq(y) (5)
60
Art of Multiprocessor Programming 60 Example time q.enq(x) q.enq(y) q.deq(y) q.enq(x) q.enq(y) (5)
61
Art of Multiprocessor Programming 61 Example time q.enq(x) q.enq(y) q.deq(y) q.enq(x) q.enq(y) (5) not linearizable
62
Art of Multiprocessor Programming 62 Example time (4)
63
Art of Multiprocessor Programming 63 Example time q.enq(x) time (4)
64
Art of Multiprocessor Programming 64 Example time q.enq(x) q.deq(x) time (4)
65
Art of Multiprocessor Programming 65 Example time q.enq(x) q.deq(x) q.enq(x) q.deq(x) time (4)
66
Art of Multiprocessor Programming 66 Example time q.enq(x) q.deq(x) q.enq(x) q.deq(x) linearizable time (4)
67
Art of Multiprocessor Programming 67 Example time q.enq(x) time (8)
68
Art of Multiprocessor Programming 68 Example time q.enq(x) q.enq(y) time (8)
69
Art of Multiprocessor Programming 69 Example time q.enq(x) q.enq(y) q.deq(y) time (8)
70
Art of Multiprocessor Programming 70 Example time q.enq(x) q.enq(y) q.deq(y) q.deq(x) time (8)
71
Art of Multiprocessor Programming 71 q.enq(x) q.enq(y) q.deq(y) q.deq(x) Example time multiple orders OK linearizable
72
Art of Multiprocessor Programming 72 Read/Write Register Example time read(1)write(0) write(1) write(2) time read(0) (4)
73
Art of Multiprocessor Programming 73 Read/Write Register Example time read(1)write(0) write(1) write(2) time read(0) write(1) already happened (4)
74
Art of Multiprocessor Programming 74 Read/Write Register Example time read(1)write(0) write(1) write(2) time read(0) write(1) write(1) already happened (4)
75
Art of Multiprocessor Programming 75 Read/Write Register Example time read(1)write(0) write(1) write(2) time read(0) write(1) write(1) already happened (4) not linearizable
76
Art of Multiprocessor Programming 76 Read/Write Register Example time read(1)write(0) write(1) write(2) time read(1) write(1) already happened (4)
77
Art of Multiprocessor Programming 77 Read/Write Register Example time read(1)write(0) write(1) write(2) time read(1) write(1)write(2) (4) write(1) already happened
78
Art of Multiprocessor Programming 78 Read/Write Register Example time read(1)write(0) write(1) write(2) time read(1) write(1)write(2) not linearizable (4) write(1) already happened
79
Art of Multiprocessor Programming 79 Read/Write Register Example time write(0) write(1) write(2) time read(1) (4)
80
Art of Multiprocessor Programming 80 Read/Write Register Example time write(0) write(1) write(2) time read(1) write(1) write(2) (4)
81
Art of Multiprocessor Programming 81 Read/Write Register Example time write(0) write(1) write(2) time read(1) write(1) write(2) linearizable (4)
82
Art of Multiprocessor Programming 82 Read/Write Register Example time read(1)write(0) write(1) write(2) time read(1) (2)
83
Art of Multiprocessor Programming 83 Read/Write Register Example time read(1)write(0) write(1) write(2) time read(1) write(1) (2)
84
Art of Multiprocessor Programming 84 Read/Write Register Example time read(1)write(0) write(1) write(2) time read(1) write(1)write(2) (2)
85
Art of Multiprocessor Programming 85 Read/Write Register Example time read(1)write(0) write(1) write(2) time read(2) write(1)write(2) Not linearizable (2)
86
Art of Multiprocessor Programming 86 Talking About Executions Why? –Can ’ t we specify the linearization point of each operation without describing an execution? Not Always –In some cases, linearization point depends on the execution
87
Art of Multiprocessor Programming 87 Formal Model of Executions Define precisely what we mean –Ambiguity is bad when intuition is weak Allow reasoning
88
Art of Multiprocessor Programming 88 Split Method Calls into Two Events Invocation –method name & args –q.enq(x) Response –result or exception –q.enq(x) returns void –q.deq() returns x –q.deq() throws empty
89
Art of Multiprocessor Programming 89 Invocation Notation A q.enq(x) (4)
90
Art of Multiprocessor Programming 90 Invocation Notation A q.enq(x) thread (4)
91
Art of Multiprocessor Programming 91 Invocation Notation A q.enq(x) thread method (4)
92
Art of Multiprocessor Programming 92 Invocation Notation A q.enq(x) thread object (4) method
93
Art of Multiprocessor Programming 93 Invocation Notation A q.enq(x) thread object method arguments (4)
94
Art of Multiprocessor Programming 94 Response Notation A q: void (2)
95
Art of Multiprocessor Programming 95 Response Notation A q: void thread (2)
96
Art of Multiprocessor Programming 96 Response Notation A q: void thread result (2)
97
Art of Multiprocessor Programming 97 Response Notation A q: void thread object result (2)
98
Art of Multiprocessor Programming 98 Response Notation A q: void thread object result (2) Method is implicit
99
Art of Multiprocessor Programming 99 Response Notation A q: empty() thread object (2) Method is implicit exception
100
Art of Multiprocessor Programming 100 History - Describing an Execution A q.enq(3) A q:void A q.enq(5) B p.enq(4) B p:void B q.deq() B q:3 Sequence of invocations and responses H =
101
Art of Multiprocessor Programming 101 Definition Invocation & response match if A q.enq(3) A q:void Thread names agree Object names agree Method call (1)
102
Art of Multiprocessor Programming 102 Object Projections A q.enq(3) A q:void B p.enq(4) B p:void B q.deq() B q:3 H =
103
Art of Multiprocessor Programming 103 Object Projections A q.enq(3) A q:void B p.enq(4) B p:void B q.deq() B q:3 H|q =
104
Art of Multiprocessor Programming 104 Thread Projections A q.enq(3) A q:void B p.enq(4) B p:void B q.deq() B q:3 H =
105
Art of Multiprocessor Programming 105 Thread Projections A q.enq(3) A q:void B p.enq(4) B p:void B q.deq() B q:3 H|B =
106
Art of Multiprocessor Programming 106 Complete Subhistory A q.enq(3) A q:void A q.enq(5) B p.enq(4) B p:void B q.deq() B q:3 An invocation is pending if it has no matching respnse H =
107
Art of Multiprocessor Programming 107 Complete Subhistory A q.enq(3) A q:void A q.enq(5) B p.enq(4) B p:void B q.deq() B q:3 May or may not have taken effect H =
108
Art of Multiprocessor Programming 108 Complete Subhistory A q.enq(3) A q:void A q.enq(5) B p.enq(4) B p:void B q.deq() B q:3 discard pending invocations H =
109
Art of Multiprocessor Programming 109 Complete Subhistory A q.enq(3) A q:void B p.enq(4) B p:void B q.deq() B q:3 Complete(H) =
110
Art of Multiprocessor Programming 110 Sequential Histories A q.enq(3) A q:void B p.enq(4) B p:void B q.deq() B q:3 A q:enq(5) (4)
111
Art of Multiprocessor Programming 111 Sequential Histories A q.enq(3) A q:void B p.enq(4) B p:void B q.deq() B q:3 A q:enq(5) match (4)
112
Art of Multiprocessor Programming 112 Sequential Histories A q.enq(3) A q:void B p.enq(4) B p:void B q.deq() B q:3 A q:enq(5) match (4)
113
Art of Multiprocessor Programming 113 Sequential Histories A q.enq(3) A q:void B p.enq(4) B p:void B q.deq() B q:3 A q:enq(5) match (4)
114
Art of Multiprocessor Programming 114 Sequential Histories A q.enq(3) A q:void B p.enq(4) B p:void B q.deq() B q:3 A q:enq(5) match Final pending invocation OK (4)
115
Art of Multiprocessor Programming 115 Sequential Histories A q.enq(3) A q:void B p.enq(4) B p:void B q.deq() B q:3 A q:enq(5) match Final pending invocation OK (4) Method calls of different threads do not interleave
116
Art of Multiprocessor Programming 116 Well-Formed Histories H= A q.enq(3) B p.enq(4) B p:void B q.deq() A q:void B q:3
117
Art of Multiprocessor Programming 117 Well-Formed Histories H= A q.enq(3) B p.enq(4) B p:void B q.deq() A q:void B q:3 H|B= B p.enq(4) B p:void B q.deq() B q:3 Per-thread projections sequential
118
Art of Multiprocessor Programming 118 Well-Formed Histories H= A q.enq(3) B p.enq(4) B p:void B q.deq() A q:void B q:3 H|B= B p.enq(4) B p:void B q.deq() B q:3 A q.enq(3) A q:void H|A= Per-thread projections sequential
119
Art of Multiprocessor Programming 119 Equivalent Histories H= A q.enq(3) B p.enq(4) B p:void B q.deq() A q:void B q:3 Threads see the same thing in both A q.enq(3) A q:void B p.enq(4) B p:void B q.deq() B q:3 G= H|A = G|A H|B = G|B
120
Art of Multiprocessor Programming 120 Sequential Specifications A sequential specification is some way of telling whether a –Single-thread, single-object history –Is legal For example: –Pre and post-conditions –But plenty of other techniques exist …
121
Art of Multiprocessor Programming 121 Legal Histories A sequential (multi-object) history H is legal if –For every object x –H|x is in the sequential spec for x
122
Art of Multiprocessor Programming 122 Precedence A q.enq(3) B p.enq(4) B p.void A q:void B q.deq() B q:3 A method call precedes another if response event precedes invocation event Method call (1)
123
Art of Multiprocessor Programming 123 Non-Precedence A q.enq(3) B p.enq(4) B p.void B q.deq() A q:void B q:3 Some method calls overlap one another Method call (1)
124
Art of Multiprocessor Programming 124 Notation Given –History H –method executions m 0 and m 1 in H We say m 0 H m 1, if –m 0 precedes m 1 Relation m 0 H m 1 is a –Partial order –Total order if H is sequential m0m0 m1m1
125
Art of Multiprocessor Programming 125 Linearizability History H is linearizable if it can be extended to G by –Appending zero or more responses to pending invocations –Discarding other pending invocations So that G is equivalent to –Legal sequential history S –where G S
126
Art of Multiprocessor Programming 126 What is G S time a b (8) GG SS c GG G = {a c,b c} S = {a b,a c,b c} A limitation on the Choice of S!
127
Art of Multiprocessor Programming 127 Remarks Some pending invocations –Took effect, so keep them –Discard the rest Condition G S –Means that S respects “ real-time order ” of G
128
Art of Multiprocessor Programming 128 A q.enq(3) B q.enq(4) B q:void B q.deq() B q:4 B q:enq(6) Example time B.q.enq(4 ) A. q.enq(3) B.q.deq(4 ) B. q.enq(6)
129
Art of Multiprocessor Programming 129 Example Complete this pending invocation time B.q.enq(4 ) B.q.deq(3 ) B. q.enq(6) A q.enq(3) B q.enq(4) B q:void B q.deq() B q:4 B q:enq(6) A. q.enq(3)
130
Art of Multiprocessor Programming 130 Example Complete this pending invocation time B.q.enq(4 ) B.q.deq(4 ) B. q.enq(6) B.q.enq(3 ) A q.enq(3) B q.enq(4) B q:void B q.deq() B q:4 B q:enq(6) A q:void
131
Art of Multiprocessor Programming 131 Example time B.q.enq(4 ) B.q.deq(4 ) B. q.enq(6) B.q.enq(3 ) A q.enq(3) B q.enq(4) B q:void B q.deq() B q:4 B q:enq(6) A q:void discard this one
132
Art of Multiprocessor Programming 132 Example time B.q.enq(4 ) B.q.deq(4 ) B.q.enq(3 ) A q.enq(3) B q.enq(4) B q:void B q.deq() B q:4 A q:void discard this one
133
Art of Multiprocessor Programming 133 A q.enq(3) B q.enq(4) B q:void B q.deq() B q:4 A q:void Example time B.q.enq(4 ) B.q.deq(4 ) B.q.enq(3 )
134
Art of Multiprocessor Programming 134 A q.enq(3) B q.enq(4) B q:void B q.deq() B q:4 A q:void Example time B q.enq(4) B q:void A q.enq(3) A q:void B q.deq() B q:4 B.q.enq(4 ) B.q.deq(4 ) B.q.enq(3 )
135
Art of Multiprocessor Programming 135 B.q.enq(4 ) B.q.deq(4 ) B.q.enq(3 ) A q.enq(3) B q.enq(4) B q:void B q.deq() B q:4 A q:void Example time B q.enq(4) B q:void A q.enq(3) A q:void B q.deq() B q:4 Equivalent sequential history
136
Art of Multiprocessor Programming 136 Concurrency How much concurrency does linearizability allow? When must a method invocation block?
137
Art of Multiprocessor Programming 137 Concurrency Focus on total methods –Defined in every state Example: –deq() that throws Empty exception –Versus deq() that waits … Why? –Otherwise, blocking unrelated to synchronization
138
Art of Multiprocessor Programming 138 Concurrency Question: When does linearizability require a method invocation to block? Answer: never. Linearizability is non-blocking
139
Art of Multiprocessor Programming 139 Non-Blocking Theorem If method invocation A q.inv( … ) is pending in history H, then there exists a response A q:res( … ) such that H + A q:res( … ) is linearizable
140
Art of Multiprocessor Programming 140 Proof Pick linearization S of H If S already contains –Invocation A q.inv( … ) and response, –Then we are done. Otherwise, pick a response such that –S + A q.inv( … ) + A q:res( … ) –Possible because object is total.
141
Art of Multiprocessor Programming 141 Composability Theorem History H is linearizable if and only if –For every object x –H|x is linearizable
142
Art of Multiprocessor Programming 142 Why Does Composability Matter? Modularity Can prove linearizability of objects in isolation Can compose independently-implemented objects
143
Art of Multiprocessor Programming 143 Reasoning About Lineraizability: Locking public T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } 0 1 capacity-1 2 head tail y z
144
Art of Multiprocessor Programming 144 Reasoning About Lineraizability: Locking public T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } Linearization points are when locks are released
145
Art of Multiprocessor Programming 145 More Reasoning: Lock-free public class LockFreeQueue { int head = 0, tail = 0; items = (T[]) new Object[capacity]; public void enq(Item x) { while (tail-head == capacity); // busy-wait items[tail % capacity] = x; tail++; } public Item deq() { while (tail == head); // busy-wait Item item = items[head % capacity]; head++; return item; }} 0 1 capacity-1 2 head tail y z
146
Art of Multiprocessor Programming 146 public class LockFreeQueue { int head = 0, tail = 0; items = (T[]) new Object[capacity]; public void enq(Item x) { while (tail-head == capacity); // busy-wait items[tail % capacity] = x; tail++; } public Item deq() { while (tail == head); // busy-wait Item item = items[head % capacity]; head++; return item; }} Linearization order is order head and tail fields modified More Reasoning Remember that there is only one enqueuer and only one dequeuer
147
Art of Multiprocessor Programming 147 Strategy Identify one atomic step where method “ happens ” –Critical section –Machine instruction Doesn ’ t always work –Might need to define several different steps for a given method
148
Art of Multiprocessor Programming 148 Linearizability: Summary Powerful specification tool for shared objects Allows us to capture the notion of objects being “ atomic ” There is a lot of ongoing research in verification community to build tools that can verify/debug concurrent implementations wrt linearizability
149
Art of Multiprocessor Programming 149 Alternative: Sequential Consistency History H is Sequentially Consistent if it can be extended to G by –Appending zero or more responses to pending invocations –Discarding other pending invocations So that G is equivalent to a –Legal sequential history S – Where G S Differs from linearizability
150
Art of Multiprocessor Programming 150 Alternative: Sequential Consistency No need to preserve real-time order –Cannot re-order operations done by the same thread –Can re-order non-overlapping operations done by different threads Often used to describe multiprocessor memory architectures
151
Art of Multiprocessor Programming 151 Example time (5)
152
Art of Multiprocessor Programming 152 Example time q.enq(x) (5)
153
Art of Multiprocessor Programming 153 Example time q.enq(x)q.deq(y) (5)
154
Art of Multiprocessor Programming 154 Example time q.enq(x) q.enq(y) q.deq(y) (5)
155
Art of Multiprocessor Programming 155 Example time q.enq(x) q.enq(y) q.deq(y) q.enq(x) q.enq(y) (5)
156
Art of Multiprocessor Programming 156 Example time q.enq(x) q.enq(y) q.deq(y) q.enq(x) q.enq(y) (5) not linearizable
157
Art of Multiprocessor Programming 157 Example time q.enq(x) q.enq(y) q.deq(y) q.enq(x) q.enq(y) (5) Yet Sequentially Consistent
158
Art of Multiprocessor Programming 158 Theorem Sequential Consistency is not a local property (and thus we lose composability … )
159
Art of Multiprocessor Programming 159 FIFO Queue Example time p.enq(x)p.deq(y)q.enq(x) time
160
Art of Multiprocessor Programming 160 FIFO Queue Example time p.enq(x)p.deq(y)q.enq(x) q.enq(y)q.deq(x)p.enq(y) time
161
Art of Multiprocessor Programming 161 FIFO Queue Example time p.enq(x)p.deq(y)q.enq(x) q.enq(y)q.deq(x)p.enq(y) History H time
162
Art of Multiprocessor Programming 162 H|p Sequentially Consistent time p.enq(x)p.deq(y) p.enq(y) q.enq(x) q.enq(y)q.deq(x) time
163
Art of Multiprocessor Programming 163 H|q Sequentially Consistent time p.enq(x)p.deq(y)q.enq(x) q.enq(y)q.deq(x)p.enq(y) time
164
Art of Multiprocessor Programming 164 Ordering imposed by p time p.enq(x)p.deq(y)q.enq(x) q.enq(y)q.deq(x)p.enq(y) time
165
Art of Multiprocessor Programming 165 Ordering imposed by q time p.enq(x)p.deq(y)q.enq(x) q.enq(y)q.deq(x)p.enq(y) time
166
Art of Multiprocessor Programming 166 p.enq(x) Ordering imposed by both time q.enq(x) q.enq(y)q.deq(x) time p.deq(y) p.enq(y)
167
Art of Multiprocessor Programming 167 p.enq(x) Combining orders time q.enq(x) q.enq(y)q.deq(x) time p.deq(y) p.enq(y)
168
Art of Multiprocessor Programming 168 Fact Most hardware architectures don ’ t support sequential consistency Because they think it ’ s too strong Here ’ s another story …
169
Art of Multiprocessor Programming 169 The Flag Example time x.write(1) y.read(0) y.write(1) x.read(0) time
170
Art of Multiprocessor Programming 170 The Flag Example time x.write(1) y.read(0) y.write(1) x.read(0) Each thread ’ s view is sequentially consistent –It went first
171
Art of Multiprocessor Programming 171 The Flag Example time x.write(1) y.read(0) y.write(1) x.read(0) Entire history isn ’ t sequentially consistent –Can ’ t both go first
172
Art of Multiprocessor Programming 172 The Flag Example time x.write(1) y.read(0) y.write(1) x.read(0) Is this behavior really so wrong? –We can argue either way …
173
Art of Multiprocessor Programming 173 Opinion1: It ’ s Wrong This pattern –Write mine, read yours Heart of mutual exclusion Peterson Bakery, etc. It ’ s non-negotiable!
174
Art of Multiprocessor Programming 174 Opinion2: But It Should be Allowed … Many hardware architects think that sequential consistency is too strong Too expensive to implement in modern hardware OK if flag principle –violated by default –Honored by explicit request
175
Art of Multiprocessor Programming 175 Memory Hierarchy On modern multiprocessors, processors do not read and write directly to memory. Memory accesses are very slow compared to processor speeds, Instead, each processor reads and writes directly to a cache
176
Art of Multiprocessor Programming 176 Memory Operations To read a memory location, –load data into cache. To write a memory location –update cached copy, –Lazily write cached data back to memory
177
Art of Multiprocessor Programming 177 While Writing to Memory A processor can execute hundreds, or even thousands of instructions Why delay on every memory write? Instead, write back in parallel with rest of the program.
178
Art of Multiprocessor Programming 178 Bottomline.. Flag violation history is actually OK –processors delay writing to memory –Until after reads have been issued. Otherwise unacceptable delay between read and write instructions. Who knew you wanted to synchronize?
179
Art of Multiprocessor Programming 179 Who knew you wanted to synchronize? Writing to memory = mailing a letter Vast majority of reads & writes –Not for synchronization –No need to idle waiting for post office If you want to synchronize –Announce it explicitly –Pay for it only when you need it
180
Art of Multiprocessor Programming 180 Explicit Synchronization Memory barrier instruction –Flush unwritten caches –Bring caches up to date Compilers often do this for you –Entering and leaving critical sections Expensive
181
Art of Multiprocessor Programming 181 Volatile In Java, can ask compiler to keep a variable up-to-date with volatile keyword Also inhibits reordering, removing from loops, & other “ optimizations ”
182
Art of Multiprocessor Programming 182 Real-World Hardware Memory Weaker than sequential consistency Examples: TSO, RMO, Intel x86… But you can get sequential consistency at a price OK for expert, tricky stuff –assembly language, device drivers, etc. Linearizability more appropriate for high-level software
183
Art of Multiprocessor Programming 183 Critical Sections Easy way to implement linearizability –Take sequential object –Make each method a critical section Problems –Blocking –No concurrency
184
Art of Multiprocessor Programming 184 Linearizability –Operation takes effect instantaneously between invocation and response –Uses sequential specification, locality implies composablity –Good for high level objects
185
Art of Multiprocessor Programming 185 Correctness: Linearizability Sequential Consistency –Not composable –Harder to work with –Good way to think about hardware models We will use linearizability as in the remainder of this course unless stated otherwise
186
Progress We saw an implementation whose methods were lock-based (deadlock- free) We saw an implementation whose methods did not use locks (lock-free) How do they relate? Art of Multiprocessor Programming 186
187
Maximal vs. Minimal Minimal progress: in some suffix of H, some pending active invocation has a matching response (some method call eventually completes ). Art of Multiprocessor Programming 187
188
Maximal vs. Minimal Minimal progress: in some suffix of H, some pending active invocation has a matching response (some method call eventually completes ). Art of Multiprocessor Programming 188
189
Maximal vs. Minimal Minimal progress: in some suffix of H, some pending active invocation has a matching response (some method call eventually completes ). Maximal progress: in every suffix of H, every pending active invocation has a matching response (every method call always completes). Art of Multiprocessor Programming 189
190
Maximal vs. Minimal Minimal progress: in some suffix of H, some pending active invocation has a matching response (some method call eventually completes ). Maximal progress: in every suffix of H, every pending active invocation has a matching response (every method call always completes). Art of Multiprocessor Programming 190
191
Progress Conditions Deadlock-free: some thread trying to acquire the lock eventually succeeds. Starvation-free: every thread trying to acquire the lock eventually succeeds. Lock-free: some thread calling a method eventually returns. Wait-free: every thread calling a method eventually returns. Art of Multiprocessor Programming 191
192
Progress Conditions Art of Multiprocessor Programming 192 Wait-free Lock-free Starvation-free Deadlock-free Everyone makes progress Non-Blocking Blocking Someone makes progress
193
Art of Multiprocessor Programming 193 Summary We will look at linearizable blocking and non-blocking implementations of objects.
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.