Download presentation
Presentation is loading. Please wait.
Published byAliya Feller Modified over 10 years ago
1
Linked Lists: Locking, Lock-Free, and Beyond … Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit
2
Art of Multiprocessor Programming2 Last Lecture: Spin-Locks CS Resets lock upon exit spin lock critical section...
3
Art of Multiprocessor Programming3 Today: Concurrent Objects Adding threads should not lower throughput –Contention effects –Mostly fixed by Queue locks
4
Art of Multiprocessor Programming4 Today: Concurrent Objects Adding threads should not lower throughput –Contention effects –Mostly fixed by Queue locks Should increase throughput –Not possible if inherently sequential –Surprising things are parallelizable
5
Art of Multiprocessor Programming5 Coarse-Grained Synchronization Each method locks the object –Avoid contention using queue locks
6
Art of Multiprocessor Programming6 Coarse-Grained Synchronization Each method locks the object –Avoid contention using queue locks –Easy to reason about In simple cases
7
Art of Multiprocessor Programming7 Coarse-Grained Synchronization Each method locks the object –Avoid contention using queue locks –Easy to reason about In simple cases So, are we done?
8
Art of Multiprocessor Programming8 Coarse-Grained Synchronization Sequential bottleneck –Threads stand in line
9
Art of Multiprocessor Programming9 Coarse-Grained Synchronization Sequential bottleneck –Threads stand in line Adding more threads –Does not improve throughput –Struggle to keep it from getting worse
10
Art of Multiprocessor Programming10 Coarse-Grained Synchronization Sequential bottleneck –Threads stand in line Adding more threads –Does not improve throughput –Struggle to keep it from getting worse So why even use a multiprocessor? –Well, some apps inherently parallel …
11
Art of Multiprocessor Programming11 This Lecture Introduce four patterns –Bag of tricks … –Methods that work more than once …
12
Art of Multiprocessor Programming12 This Lecture Introduce four patterns –Bag of tricks … –Methods that work more than once … For highly-concurrent objects –Concurrent access –More threads, more throughput
13
Art of Multiprocessor Programming13 First: Fine-Grained Synchronization Instead of using a single lock … Split object into –Independently-synchronized components Methods conflict when they access –The same component … –At the same time
14
Art of Multiprocessor Programming14 Second: Optimistic Synchronization Search without locking …
15
Art of Multiprocessor Programming15 Second: Optimistic Synchronization Search without locking … If you find it, lock and check … –OK: we are done –Oops: start over
16
Art of Multiprocessor Programming16 Second: Optimistic Synchronization Search without locking … If you find it, lock and check … –OK: we are done –Oops: start over Evaluation –Usually cheaper than locking, but –Mistakes are expensive
17
Art of Multiprocessor Programming17 Third: Lazy Synchronization Postpone hard work Removing components is tricky –Logical removal Mark component to be deleted –Physical removal Do what needs to be done
18
Art of Multiprocessor Programming18 Fourth: Lock-Free Synchronization Dont use locks at all –Use compareAndSet() & relatives …
19
Art of Multiprocessor Programming19 Fourth: Lock-Free Synchronization Dont use locks at all –Use compareAndSet() & relatives … Advantages –No Scheduler Assumptions/Support
20
Art of Multiprocessor Programming20 Fourth: Lock-Free Synchronization Dont use locks at all –Use compareAndSet() & relatives … Advantages –No Scheduler Assumptions/Support Disadvantages –Complex –Sometimes high overhead
21
Art of Multiprocessor Programming21 Linked List Illustrate these patterns … Using a list-based Set –Common application –Building block for other apps
22
Art of Multiprocessor Programming22 Set Interface Unordered collection of items
23
Art of Multiprocessor Programming23 Set Interface Unordered collection of items No duplicates
24
Art of Multiprocessor Programming24 Set Interface Unordered collection of items No duplicates Methods –add(x) put x in set –remove(x) take x out of set –contains(x) tests if x in set
25
Art of Multiprocessor Programming25 List-Based Sets public interface Set { public boolean add(T x); public boolean remove(T x); public boolean contains(T x); }
26
Art of Multiprocessor Programming26 List-Based Sets public interface Set { public boolean add(T x); public boolean remove(T x); public boolean contains(T x); } Add item to set
27
Art of Multiprocessor Programming27 List-Based Sets public interface Set { public boolean add(T x); public boolean remove(T x); public boolean contains(Tt x); } Remove item from set
28
Art of Multiprocessor Programming28 List-Based Sets public interface Set { public boolean add(T x); public boolean remove(T x); public boolean contains(T x); } Is item in set?
29
Art of Multiprocessor Programming29 List Node public class Node { public T item; public int key; public Node next; }
30
Art of Multiprocessor Programming30 List Node public class Node { public T item; public int key; public Node next; } item of interest
31
Art of Multiprocessor Programming31 List Node public class Node { public T item; public int key; public Node next; } Usually hash code
32
Art of Multiprocessor Programming32 List Node public class Node { public T item; public int key; public Node next; } Reference to next node
33
Art of Multiprocessor Programming33 The List-Based Set abc Sorted with Sentinel nodes (min & max possible keys) - +
34
Art of Multiprocessor Programming34 Reasoning about Concurrent Objects Invariant –Property that always holds
35
Art of Multiprocessor Programming35 Reasoning about Concurrent Objects Invariant –Property that always holds Established because –True when object is created –Truth preserved by each method Each step of each method
36
Art of Multiprocessor Programming36 Specifically … Invariants preserved by –add() –remove() –contains()
37
Art of Multiprocessor Programming37 Specifically … Invariants preserved by –add() –remove() –contains() Most steps are trivial –Usually one step tricky –Often linearization point
38
Art of Multiprocessor Programming38 Interference Invariants make sense only if –methods considered –are the only modifiers
39
Art of Multiprocessor Programming39 Interference Invariants make sense only if –methods considered –are the only modifiers Language encapsulation helps –List nodes not visible outside class
40
Art of Multiprocessor Programming40 Interference Invariants make sense only if –methods considered –are the only modifiers Language encapsulation helps –List nodes not visible outside class
41
Art of Multiprocessor Programming41 Interference Freedom from interference needed even for removed nodes –Some algorithms traverse removed nodes –Careful with malloc() & free() ! Garbage collection helps here
42
Art of Multiprocessor Programming42 Abstract Data Types Concrete representation: Abstract Type: –{a, b} ab
43
Art of Multiprocessor Programming43 Abstract Data Types Meaning of rep given by abstraction map –S( ) = {a,b} a b
44
Art of Multiprocessor Programming44 Rep Invariant Which concrete values meaningful? –Sorted? –Duplicates? Rep invariant –Characterizes legal concrete reps –Preserved by methods –Relied on by methods
45
Art of Multiprocessor Programming45 Blame Game Rep invariant is a contract Suppose –add() leaves behind 2 copies of x –remove() removes only 1 Which is incorrect?
46
Art of Multiprocessor Programming46 Blame Game Suppose –add() leaves behind 2 copies of x –remove() removes only 1
47
Art of Multiprocessor Programming47 Blame Game Suppose –add() leaves behind 2 copies of x –remove() removes only 1 Which is incorrect? –If rep invariant says no duplicates add() is incorrect –Otherwise remove() is incorrect
48
Art of Multiprocessor Programming48 Rep Invariant (partly) Sentinel nodes –tail reachable from head Sorted No duplicates
49
Art of Multiprocessor Programming49 Abstraction Map S(head) = { x | there exists a such that a reachable from head and a.item = x }
50
Art of Multiprocessor Programming50 Sequential List Based Set a c d a b c add() remove()
51
Art of Multiprocessor Programming51 Sequential List Based Set a c d b a b c add() r emove()
52
Art of Multiprocessor Programming52 Coarse-Grained Locking a b d
53
Art of Multiprocessor Programming53 Coarse-Grained Locking a b d c
54
Art of Multiprocessor Programming54 honk! Coarse-Grained Locking a b d c Simple but hotspot + bottleneck honk!
55
Art of Multiprocessor Programming55 Coarse-Grained Locking Easy, same as synchronized methods –One lock to rule them all …
56
Art of Multiprocessor Programming56 Coarse-Grained Locking Easy, same as synchronized methods –One lock to rule them all … Simple, clearly correct –Deserves respect! Works poorly with contention –Queue locks help –But bottleneck still an issue
57
Art of Multiprocessor Programming57 Fine-grained Locking Requires careful thought –Do not meddle in the affairs of wizards, for they are subtle and quick to anger
58
Art of Multiprocessor Programming58 Fine-grained Locking Requires careful thought –Do not meddle in the affairs of wizards, for they are subtle and quick to anger Split object into pieces –Each piece has own lock –Methods that work on disjoint pieces need not exclude each other
59
Art of Multiprocessor Programming59 Hand-over-Hand locking abc
60
Art of Multiprocessor Programming60 Hand-over-Hand locking abc
61
Art of Multiprocessor Programming61 Hand-over-Hand locking abc
62
Art of Multiprocessor Programming62 Hand-over-Hand locking abc
63
Art of Multiprocessor Programming63 Hand-over-Hand locking abc
64
Art of Multiprocessor Programming64 Removing a Node abcd remove(b)
65
Art of Multiprocessor Programming65 Removing a Node abcd remove(b)
66
Art of Multiprocessor Programming66 Removing a Node abcd remove(b)
67
Art of Multiprocessor Programming67 Removing a Node abcd remove(b)
68
Art of Multiprocessor Programming68 Removing a Node abcd remove(b)
69
Art of Multiprocessor Programming69 Removing a Node acd remove(b) Why lock victim node?
70
Art of Multiprocessor Programming70 Concurrent Removes abcd remove(c) remove(b)
71
Art of Multiprocessor Programming71 Concurrent Removes abcd remove(b) remove(c)
72
Art of Multiprocessor Programming72 Concurrent Removes abcd remove(b) remove(c)
73
Art of Multiprocessor Programming73 Concurrent Removes abcd remove(b) remove(c)
74
Art of Multiprocessor Programming74 Concurrent Removes abcd remove(b) remove(c)
75
Art of Multiprocessor Programming75 Concurrent Removes abcd remove(b) remove(c)
76
Art of Multiprocessor Programming76 Concurrent Removes abcd remove(b) remove(c)
77
Art of Multiprocessor Programming77 Concurrent Removes abcd remove(b) remove(c)
78
Art of Multiprocessor Programming78 Concurrent Removes abcd remove(b) remove(c)
79
Art of Multiprocessor Programming79 Concurrent Removes abcd remove(b) remove(c)
80
Art of Multiprocessor Programming80 Uh, Oh acd remove(b) remove(c)
81
Art of Multiprocessor Programming81 Uh, Oh acd Bad news, c not removed remove(b) remove(c)
82
Art of Multiprocessor Programming82 Problem To delete node c –Swing node bs next field to d Problem is, –Someone deleting b concurrently could direct a pointer to c ba cbac
83
Art of Multiprocessor Programming83 Insight If a node is locked –No one can delete nodes successor If a thread locks –Node to be deleted –And its predecessor –Then it works
84
Art of Multiprocessor Programming84 Hand-Over-Hand Again abcd remove(b)
85
Art of Multiprocessor Programming85 Hand-Over-Hand Again abcd remove(b)
86
Art of Multiprocessor Programming86 Hand-Over-Hand Again abcd remove(b)
87
Art of Multiprocessor Programming87 Hand-Over-Hand Again abcd remove(b) Found it!
88
Art of Multiprocessor Programming88 Hand-Over-Hand Again abcd remove(b) Found it!
89
Art of Multiprocessor Programming89 Hand-Over-Hand Again acd remove(b)
90
Art of Multiprocessor Programming90 Removing a Node abcd remove(b) remove(c)
91
Art of Multiprocessor Programming91 Removing a Node abcd remove(b) remove(c)
92
Art of Multiprocessor Programming92 Removing a Node abcd remove(b) remove(c)
93
Art of Multiprocessor Programming93 Removing a Node abcd remove(b) remove(c)
94
Art of Multiprocessor Programming94 Removing a Node abcd remove(b) remove(c)
95
Art of Multiprocessor Programming95 Removing a Node abcd remove(b) remove(c)
96
Art of Multiprocessor Programming96 Removing a Node abcd remove(b) remove(c)
97
Art of Multiprocessor Programming97 Removing a Node abcd remove(b) remove(c)
98
Art of Multiprocessor Programming98 Removing a Node abcd Must acquire Lock for b remove(c)
99
Art of Multiprocessor Programming99 Removing a Node abcd Waiting to acquire lock for b remove(c)
100
Art of Multiprocessor Programming100 Removing a Node abcd Wait! remove(c)
101
Art of Multiprocessor Programming101 Removing a Node abd Proceed to remove(b)
102
Art of Multiprocessor Programming102 Removing a Node abd remove(b)
103
Art of Multiprocessor Programming103 Removing a Node abd remove(b)
104
Art of Multiprocessor Programming104 Removing a Node ad remove(b)
105
Art of Multiprocessor Programming105 Removing a Node ad
106
Art of Multiprocessor Programming106 Remove method public boolean remove(T item) { int key = item.hashCode(); Node pred, curr; try { … } finally { curr.unlock(); pred.unlock(); }}
107
Art of Multiprocessor Programming107 Remove method public boolean remove(T item) { int key = item.hashCode(); Node pred, curr; try { … } finally { curr.unlock(); pred.unlock(); }} Key used to order node
108
Art of Multiprocessor Programming108 Remove method public boolean remove(T item) { int key = item.hashCode(); Node pred, curr; try { … } finally { currNode.unlock(); predNode.unlock(); }} Predecessor and current nodes
109
Art of Multiprocessor Programming109 Remove method public boolean remove(T item) { int key = item.hashCode(); Node pred, curr; try { … } finally { curr.unlock(); pred.unlock(); }} Make sure locks released
110
Art of Multiprocessor Programming110 Remove method public boolean remove(T item) { int key = item.hashCode(); Node pred, curr; try { … } finally { curr.unlock(); pred.unlock(); }} Everything else
111
Art of Multiprocessor Programming111 Remove method try { pred = head; pred.lock(); curr = pred.next; curr.lock(); … } finally { … }
112
Art of Multiprocessor Programming112 Remove method try { pred = head; pred.lock(); curr = pred.next; curr.lock(); … } finally { … } lock pred == head
113
try { pred = head; pred.lock(); curr = pred.next; curr.lock(); … } finally { … } Art of Multiprocessor Programming113 Remove method Lock current
114
try { pred = head; pred.lock(); curr = pred.next; curr.lock(); … } finally { … } Art of Multiprocessor Programming114 Remove method Traversing list
115
while (curr.key <= key) { if (item == curr.item) { pred.next = curr.next; return true; } pred.unlock(); pred = curr; curr = curr.next; curr.lock(); } return false; Art of Multiprocessor Programming115 Remove: searching
116
while (curr.key <= key) { if (item == curr.item) { pred.next = curr.next; return true; } pred.unlock(); pred = curr; curr = curr.next; curr.lock(); } return false; Art of Multiprocessor Programming116 Remove: searching Search key range
117
while (curr.key <= key) { if (item == curr.item) { pred.next = curr.next; return true; } pred.unlock(); pred = curr; curr = curr.next; curr.lock(); } return false; At start of each loop: curr and pred locked Art of Multiprocessor Programming117 Remove: searching
118
while (curr.key <= key) { if (item == curr.item) { pred.next = curr.next; return true; } pred.unlock(); pred = curr; curr = curr.next; curr.lock(); } return false; Art of Multiprocessor Programming118 Remove: searching If item found, remove node
119
while (curr.key <= key) { if (item == curr.item) { pred.next = curr.next; return true; } pred.unlock(); pred = curr; curr = curr.next; curr.lock(); } return false; Art of Multiprocessor Programming119 Remove: searching If node found, remove it
120
while (curr.key <= key) { if (item == curr.item) { pred.next = curr.next; return true; } pred.unlock(); pred = curr; curr = curr.next; curr.lock(); } return false; Art of Multiprocessor Programming120 Remove: searching Unlock predecessor
121
while (curr.key <= key) { if (item == curr.item) { pred.next = curr.next; return true; } pred.unlock(); pred = curr; curr = curr.next; curr.lock(); } return false; Art of Multiprocessor Programming121 Remove: searching Only one node locked!
122
while (curr.key <= key) { if (item == curr.item) { pred.next = curr.next; return true; } pred.unlock(); pred = curr; curr = curr.next; curr.lock(); } return false; Art of Multiprocessor Programming122 Remove: searching demote current
123
while (curr.key <= key) { if (item == curr.item) { pred.next = curr.next; return true; } pred.unlock(); pred = currNode; curr = curr.next; curr.lock(); } return false; Art of Multiprocessor Programming123 Remove: searching Find and lock new current
124
while (curr.key <= key) { if (item == curr.item) { pred.next = curr.next; return true; } pred.unlock(); pred = currNode; curr = curr.next; curr.lock(); } return false; Art of Multiprocessor Programming124 Remove: searching Lock invariant restored
125
Art of Multiprocessor Programming125 Remove: searching while (curr.key <= key) { if (item == curr.item) { pred.next = curr.next; return true; } pred.unlock(); pred = curr; curr = curr.next; curr.lock(); } return false; Otherwise, not present
126
Art of Multiprocessor Programming126 Why does this work? To remove node e –Must lock e –Must lock es predecessor Therefore, if you lock a node –It cant be removed –And neither can its successor
127
Art of Multiprocessor Programming127 while (curr.key <= key) { if (item == curr.item) { pred.next = curr.next; return true; } pred.unlock(); pred = curr; curr = curr.next; curr.lock(); } return false; Why remove() is linearizable pred reachable from head curr is pred.next So curr.item is in the set
128
Art of Multiprocessor Programming128 while (curr.key <= key) { if (item == curr.item) { pred.next = curr.next; return true; } pred.unlock(); pred = curr; curr = curr.next; curr.lock(); } return false; Why remove() is linearizable Linearization point if item is present
129
Art of Multiprocessor Programming129 while (curr.key <= key) { if (item == curr.item) { pred.next = curr.next; return true; } pred.unlock(); pred = curr; curr = curr.next; curr.lock(); } return false; Why remove() is linearizable Node locked, so no other thread can remove it ….
130
Art of Multiprocessor Programming130 while (curr.key <= key) { if (item == curr.item) { pred.next = curr.next; return true; } pred.unlock(); pred = curr; curr = curr.next; curr.lock(); } return false; Why remove() is linearizable Item not present
131
Art of Multiprocessor Programming131 while (curr.key <= key) { if (item == curr.item) { pred.next = curr.next; return true; } pred.unlock(); pred = curr; curr = curr.next; curr.lock(); } return false; Why remove() is linearizable pred reachable from head curr is pred.next pred.key < key key < curr.key
132
Art of Multiprocessor Programming132 while (curr.key <= key) { if (item == curr.item) { pred.next = curr.next; return true; } pred.unlock(); pred = curr; curr = curr.next; curr.lock(); } return false; Why remove() is linearizable Linearization point
133
Art of Multiprocessor Programming133 Adding Nodes To add node e –Must lock predecessor –Must lock successor Neither can be deleted –(Is successor lock actually required?)
134
Art of Multiprocessor Programming134 Same Abstraction Map S(head) = { x | there exists a such that a reachable from head and a.item = x }
135
Art of Multiprocessor Programming135 Rep Invariant Easy to check that –tail always reachable from head –Nodes sorted, no duplicates
136
Art of Multiprocessor Programming136 Drawbacks Better than coarse-grained lock –Threads can traverse in parallel Still not ideal –Long chain of acquire/release –Inefficient
137
Art of Multiprocessor Programming137 Optimistic Synchronization Find nodes without locking Lock nodes Check that everything is OK
138
Art of Multiprocessor Programming138 Optimistic: Traverse without Locking b d e a add(c) Aha!
139
Art of Multiprocessor Programming139 Optimistic: Lock and Load b d e a add(c)
140
Art of Multiprocessor Programming140 Optimistic: Lock and Load b d e a add(c) c
141
Art of Multiprocessor Programming141 What could go wrong? b d e a add(c) Aha!
142
Art of Multiprocessor Programming142 What could go wrong? b d e a add(c)
143
Art of Multiprocessor Programming143 What could go wrong? b d e a remove(b)
144
Art of Multiprocessor Programming144 What could go wrong? b d e a remove(b)
145
Art of Multiprocessor Programming145 What could go wrong? b d e a add(c)
146
Art of Multiprocessor Programming146 What could go wrong? b d e a add(c) c
147
Art of Multiprocessor Programming147 What could go wrong? d e a add(c) Uh-oh
148
Art of Multiprocessor Programming148 Validate – Part 1 b d e a add(c) Yes, b still reachable from head
149
Art of Multiprocessor Programming149 What Else Could Go Wrong? b d e a add(c) Aha!
150
Art of Multiprocessor Programming150 What Else Coould Go Wrong? b d e a add(c) add(b)
151
Art of Multiprocessor Programming151 What Else Coould Go Wrong? b d e a add(c) add(b) b
152
Art of Multiprocessor Programming152 What Else Could Go Wrong? b d e a add(c) b
153
Art of Multiprocessor Programming153 What Else Could Go Wrong? b d e a add(c) c
154
Art of Multiprocessor Programming154 Validate Part 2 (while holding locks) b d e a add(c) Yes, b still points to d
155
Art of Multiprocessor Programming155 Optimistic: Linearization Point b d e a add(c) c
156
Art of Multiprocessor Programming156 Same Abstraction Map S(head) = { x | there exists a such that a reachable from head and a.item = x }
157
Art of Multiprocessor Programming157 Invariants Careful: we may traverse deleted nodes But we establish properties by –Validation –After we lock target nodes
158
Art of Multiprocessor Programming158 Correctness If –Nodes b and c both locked –Node b still accessible –Node c still successor to b Then –Neither will be deleted –OK to delete and return true
159
Art of Multiprocessor Programming159 Unsuccessful Remove abde remove(c) Aha!
160
Art of Multiprocessor Programming160 Validate (1) abde Yes, b still reachable from head remove(c)
161
Art of Multiprocessor Programming161 Validate (2) abde remove(c) Yes, b still points to d
162
Art of Multiprocessor Programming162 OK Computer abde remove(c) return false
163
Art of Multiprocessor Programming163 Correctness If –Nodes b and d both locked –Node b still accessible –Node d still successor to b Then –Neither will be deleted –No thread can add c after b –OK to return false
164
Art of Multiprocessor Programming164 Validation private boolean validate(Node pred, Node curry) { Node node = head; while (node.key <= pred.key) { if (node == pred) return pred.next == curr; node = node.next; } return false; }
165
private boolean validate(Node pred, Node curr) { Node node = head; while (node.key <= pred.key) { if (node == pred) return pred.next == curr; node = node.next; } return false; } Art of Multiprocessor Programming165 Validation Predecessor & current nodes
166
private boolean validate(Node pred, Node curr) { Node node = head; while (node.key <= pred.key) { if (node == pred) return pred.next == curr; node = node.next; } return false; } Art of Multiprocessor Programming166 Validation Begin at the beginning
167
private boolean validate(Node pred, Node curr) { Node node = head; while (node.key <= pred.key) { if (node == pred) return pred.next == curr; node = node.next; } return false; } Art of Multiprocessor Programming167 Validation Search range of keys
168
private boolean validate(Node pred, Node curr) { Node node = head; while (node.key <= pred.key) { if (node == pred) return pred.next == curr; node = node.next; } return false; } Art of Multiprocessor Programming168 Validation Predecessor reachable
169
Art of Multiprocessor Programming169 private boolean validate(Node pred, Node curr) { Node node = head; while (node.key <= pred.key) { if (node == pred) return pred.next == curr; node = node.next; } return false; } Validation Is current node next?
170
Art of Multiprocessor Programming170 private boolean validate(Node pred, Node curr) { Node node = head; while (node.key <= pred.key) { if (node == pred) return pred.next == curr; node = node.next; } return false; } Validation Otherwise move on
171
Art of Multiprocessor Programming171 private boolean validate(Node pred, Node curr) { Node node = head; while (node.key <= pred.key) { if (node == pred) return pred.next == curr; node = node.next; } return false; } Validation Predecessor not reachable
172
Art of Multiprocessor Programming172 Remove: searching public boolean remove(T item) { int key = item.hashCode(); retry: while (true) { Node pred = head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; } …
173
Art of Multiprocessor Programming173 public boolean remove(T item) { int key = item.hashCode(); retry: while (true) { Node pred = head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; } … Remove: searching Search key
174
Art of Multiprocessor Programming174 public boolean remove(T item) { int key = item.hashCode(); retry: while (true) { Node pred = head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; } … Remove: searching Retry on synchronization conflict
175
Art of Multiprocessor Programming175 public boolean remove(T item) { int key = item.hashCode(); retry: while (true) { Node pred = head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; } … Remove: searching Examine predecessor and current nodes
176
Art of Multiprocessor Programming176 public boolean remove(T item) { int key = item.hashCode(); retry: while (true) { Node pred = head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; } … Remove: searching Search by key
177
Art of Multiprocessor Programming177 public boolean remove(T item) { int key = item.hashCode(); retry: while (true) { Node pred = head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; } … Remove: searching Stop if we find item
178
Art of Multiprocessor Programming178 public boolean remove(T item) { int key = item.hashCode(); retry: while (true) { Node pred = head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; } … Remove: searching Move along
179
Art of Multiprocessor Programming179 On Exit from Loop If item is present –curr holds item –pred just before curr If item is absent –curr has first higher key –pred just before curr Assuming no synchronization problems
180
Art of Multiprocessor Programming180 Remove Method try { pred.lock(); curr.lock(); if (validate(pred,curr) { if (curr.item == item) { pred.next = curr.next; return true; } else { return false; }}} finally { pred.unlock(); curr.unlock(); }}}
181
Art of Multiprocessor Programming181 try { pred.lock(); curr.lock(); if (validate(pred,curr) { if (curr.item == item) { pred.next = curr.next; return true; } else { return false; }}} finally { pred.unlock(); curr.unlock(); }}} Remove Method Always unlock
182
Art of Multiprocessor Programming182 try { pred.lock(); curr.lock(); if (validate(pred,curr) { if (curr.item == item) { pred.next = curr.next; return true; } else { return false; }}} finally { pred.unlock(); curr.unlock(); }}} Remove Method Lock both nodes
183
Art of Multiprocessor Programming183 try { pred.lock(); curr.lock(); if (validate(pred,curr) { if (curr.item == item) { pred.next = curr.next; return true; } else { return false; }}} finally { pred.unlock(); curr.unlock(); }}} Remove Method Check for synchronization conflicts
184
Art of Multiprocessor Programming184 try { pred.lock(); curr.lock(); if (validate(pred,curr) { if (curr.item == item) { pred.next = curr.next; return true; } else { return false; }}} finally { pred.unlock(); curr.unlock(); }}} Remove Method target found, remove node
185
Art of Multiprocessor Programming185 try { pred.lock(); curr.lock(); if (validate(pred,curr) { if (curr.item == item) { pred.next = curr.next; return true; } else { return false; }}} finally { pred.unlock(); curr.unlock(); }}} Remove Method target not found
186
Art of Multiprocessor Programming186 Optimistic List Limited hot-spots –Targets of add(), remove(), contains() –No contention on traversals Moreover –Traversals are wait-free –Food for thought …
187
Art of Multiprocessor Programming187 So Far, So Good Much less lock acquisition/release –Performance –Concurrency Problems –Need to traverse list twice –contains() method acquires locks
188
Art of Multiprocessor Programming188 Evaluation Optimistic is effective if –cost of scanning twice without locks is less than –cost of scanning once with locks Drawback –contains() acquires locks –90% of calls in many apps
189
Art of Multiprocessor Programming189 Lazy List Like optimistic, except –Scan once –contains(x) never locks … Key insight –Removing nodes causes trouble –Do it lazily
190
Art of Multiprocessor Programming190 Lazy List remove() –Scans list (as before) –Locks predecessor & current (as before) Logical delete –Marks current node as removed (new!) Physical delete –Redirects predecessors next (as before)
191
Art of Multiprocessor Programming191 Lazy Removal aa b c d
192
c Art of Multiprocessor Programming192 Lazy Removal aa b d Present in list
193
c Art of Multiprocessor Programming193 Lazy Removal aa b d Logically deleted
194
Art of Multiprocessor Programming194 Lazy Removal aa b c d Physically deleted
195
Art of Multiprocessor Programming195 Lazy Removal aa b d Physically deleted
196
Art of Multiprocessor Programming196 Lazy List All Methods –Scan through locked and marked nodes –Removing a node doesnt slow down other method calls … Must still lock pred and curr nodes.
197
Art of Multiprocessor Programming197 Validation No need to rescan list! Check that pred is not marked Check that curr is not marked Check that pred points to curr
198
Art of Multiprocessor Programming198 Business as Usual abc
199
Art of Multiprocessor Programming199 Business as Usual abc
200
Art of Multiprocessor Programming200 Business as Usual abc
201
Art of Multiprocessor Programming201 Business as Usual abc remove(b)
202
Art of Multiprocessor Programming202 Business as Usual abc a not marked
203
Art of Multiprocessor Programming203 Business as Usual abc a still points to b
204
Art of Multiprocessor Programming204 Business as Usual a bc Logical delete
205
Art of Multiprocessor Programming205 Business as Usual a bc physical delete
206
Art of Multiprocessor Programming206 Business as Usual a bc
207
Art of Multiprocessor Programming207 New Abstraction Map S(head) = { x | there exists node a such that a reachable from head and a.item = x and a is unmarked }
208
Art of Multiprocessor Programming208 Invariant If not marked then item in the set and reachable from head and if not yet traversed it is reachable from pred
209
Art of Multiprocessor Programming209 Validation private boolean validate(Node pred, Node curr) { return !pred.marked && !curr.marked && pred.next == curr); }
210
Art of Multiprocessor Programming210 private boolean validate(Node pred, Node curr) { return !pred.marked && !curr.marked && pred.next == curr); } List Validate Method Predecessor not Logically removed
211
Art of Multiprocessor Programming211 private boolean validate(Node pred, Node curr) { return !pred.marked && !curr.marked && pred.next == curr); } List Validate Method Current not Logically removed
212
Art of Multiprocessor Programming212 private boolean validate(Node pred, Node curr) { return !pred.marked && !curr.marked && pred.next == curr); } List Validate Method Predecessor still Points to current
213
Art of Multiprocessor Programming213 Remove try { pred.lock(); curr.lock(); if (validate(pred,curr) { if (curr.key == key) { curr.marked = true; pred.next = curr.next; return true; } else { return false; }}} finally { pred.unlock(); curr.unlock(); }}}
214
Art of Multiprocessor Programming214 Remove try { pred.lock(); curr.lock(); if (validate(pred,curr) { if (curr.key == key) { curr.marked = true; pred.next = curr.next; return true; } else { return false; }}} finally { pred.unlock(); curr.unlock(); }}} Validate as before
215
Art of Multiprocessor Programming215 Remove try { pred.lock(); curr.lock(); if (validate(pred,curr) { if (curr.key == key) { curr.marked = true; pred.next = curr.next; return true; } else { return false; }}} finally { pred.unlock(); curr.unlock(); }}} Key found
216
Art of Multiprocessor Programming216 Remove try { pred.lock(); curr.lock(); if (validate(pred,curr) { if (curr.key == key) { curr.marked = true; pred.next = curr.next; return true; } else { return false; }}} finally { pred.unlock(); curr.unlock(); }}} Logical remove
217
Art of Multiprocessor Programming217 Remove try { pred.lock(); curr.lock(); if (validate(pred,curr) { if (curr.key == key) { curr.marked = true; pred.next = curr.next; return true; } else { return false; }}} finally { pred.unlock(); curr.unlock(); }}} physical remove
218
Art of Multiprocessor Programming218 Contains public boolean contains(T item) { int key = item.hashCode(); Node curr = head; while (curr.key < key) { curr = curr.next; } return curr.key == key && !curr.marked; }
219
Art of Multiprocessor Programming219 Contains public boolean contains(T item) { int key = item.hashCode(); Node curr = head; while (curr.key < key) { curr = curr.next; } return curr.key == key && !curr.marked; } Start at the head
220
Art of Multiprocessor Programming220 Contains public boolean contains(T item) { int key = item.hashCode(); Node curr = head; while (curr.key < key) { curr = curr.next; } return curr.key == key && !curr.marked; } Search key range
221
Art of Multiprocessor Programming221 Contains public boolean contains(T item) { int key = item.hashCode(); Node curr = head; while (curr.key < key) { curr = curr.next; } return curr.key == key && !curr.marked; } Traverse without locking (nodes may have been removed)
222
Art of Multiprocessor Programming222 Contains public boolean contains(T item) { int key = item.hashCode(); Node curr = head; while (curr.key < key) { curr = curr.next; } return curr.key == key && !curr.marked; } Present and undeleted?
223
Art of Multiprocessor Programming223 Summary: Wait-free Contains a 0 0 0 a b c 0 e 1 d Use Mark bit + list ordering 1.Not marked in the set 2.Marked or missing not in the set
224
Art of Multiprocessor Programming224 Lazy List a 0 0 0 a b c 0 e 1 d Lazy add() and remove() + Wait-free contains()
225
Art of Multiprocessor Programming225 Evaluation Good: –contains() doesnt lock –In fact, its wait-free! –Good because typically high % contains() –Uncontended calls dont re-traverse Bad –Contended add() and remove() calls must re-traverse –Traffic jam if one thread delays
226
Art of Multiprocessor Programming226 Traffic Jam Any concurrent data structure based on mutual exclusion has a weakness If one thread –Enters critical section –And eats the big muffin Cache miss, page fault, descheduled … –Everyone else using that lock is stuck! –Need to trust the scheduler….
227
Art of Multiprocessor Programming227 Reminder: Lock-Free Data Structures No matter what … –Guarantees minimal progress in any execution –i.e. Some thread will always complete a method call –Even if others halt at malicious times –Implies that implementation cant use locks
228
Art of Multiprocessor Programming228 Lock-free Lists Next logical step –Wait-free contains() –lock-free add() and remove() Use only compareAndSet() –What could go wrong?
229
229 public abstract class CASObject { private int value; public boolean synchronized compareAndSet(int expected, int update) { int prior = value; if (value==expected) { value = update; return true; } return false; } … } compareAndSet Art of Multiprocessor Programming
230
230 public abstract class CASObject { private int value; public boolean synchronized compareAndSet(int expected, int update) { int prior = value; if (value==expected) { value = update; return true; } return false; } … } compareAndSet If value is as expected, …
231
Art of Multiprocessor Programming 231 public abstract class CASOBJECT{ private int value; public boolean synchronized compareAndSet(int expected, int update) { int prior = value; if (value==expected) { value = update; return true; } return false; } … } compareAndSet … replace it
232
Art of Multiprocessor Programming 232 public abstract class RMWRegister { private int value; public boolean synchronized compareAndSet(int expected, int update) { int prior = value; if (value==expected) { value = update; return true; } return false; } … } compareAndSet Report success
233
Art of Multiprocessor Programming 233 public abstract class RMWRegister { private int value; public boolean synchronized compareAndSet(int expected, int update) { int prior = value; if (value==expected) { value = update; return true; } return false; } … } compareAndSet Otherwise report failure
234
Art of Multiprocessor Programming234 a 0 0 0 a b c 0 e 1 c Logical Removal Physical Removal Use CAS to verify pointer is correct Not enough! Lock-free Lists
235
Art of Multiprocessor Programming235 Problem… a 0 0 0 a b c 0 e 1 c Logical Removal Physical Removal 0 d Node added
236
Art of Multiprocessor Programming236 The Solution: Combine Bit and Pointer a 0 0 0 a b c 0 e 1 c Logical Removal = Set Mark Bit Physical Removal CAS 0 d Mark-Bit and Pointer are CASed together (AtomicMarkableReference) Fail CAS: Node not added after logical Removal
237
Art of Multiprocessor Programming237 Solution Use AtomicMarkableReference Atomically –Swing reference and –Update flag Remove in two steps –Set mark bit in next field –Redirect predecessors pointer
238
Art of Multiprocessor Programming238 Marking a Node AtomicMarkableReference class –Java.util.concurrent.atomic package address F mark bit Reference
239
Art of Multiprocessor Programming239 Extracting Reference & Mark Public Object get(boolean[] marked);
240
Art of Multiprocessor Programming240 Extracting Reference & Mark Public Object get(boolean[] marked); Returns reference Returns mark at array index 0!
241
Art of Multiprocessor Programming241 Extracting Mark Only public boolean isMarked(); Value of mark
242
Art of Multiprocessor Programming242 Changing State Public boolean compareAndSet( Object expectedRef, Object updateRef, boolean expectedMark, boolean updateMark);
243
Art of Multiprocessor Programming243 Changing State Public boolean compareAndSet( Object expectedRef, Object updateRef, boolean expectedMark, boolean updateMark); If this is the current reference … And this is the current mark …
244
Art of Multiprocessor Programming244 Changing State Public boolean compareAndSet( Object expectedRef, Object updateRef, boolean expectedMark, boolean updateMark); …then change to this new reference … … and this new mark
245
Art of Multiprocessor Programming245 Changing State public boolean attemptMark( Object expectedRef, boolean updateMark);
246
Art of Multiprocessor Programming246 Changing State public boolean attemptMark( Object expectedRef, boolean updateMark); If this is the current reference …
247
Art of Multiprocessor Programming247 Changing State public boolean attemptMark( Object expectedRef, boolean updateMark);.. then change to this new mark.
248
b CAS Art of Multiprocessor Programming248 Removing a Node acd remove c
249
Art of Multiprocessor Programming249 Removing a Node abd remove b remove c c failed CAS
250
Art of Multiprocessor Programming250 Removing a Node abd remove b remove c c
251
Art of Multiprocessor Programming251 Removing a Node ad remove b remove c
252
Art of Multiprocessor Programming252 Traversing the List Q: what do you do when you find a logically deleted node in your path? A: finish the job. –CAS the predecessors next field –Proceed (repeat as needed)
253
Art of Multiprocessor Programming253 Lock-Free Traversal (only Add and Remove) abcd CAS Uh-oh pred curr pred curr
254
Art of Multiprocessor Programming254 The Window Class class Window { public Node pred; public Node curr; Window(Node pred, Node curr) { pred = pred; curr = curr; }
255
Art of Multiprocessor Programming255 The Window Class class Window { public Node pred; public Node curr; Window(Node pred, Node curr) { pred = pred; curr = curr; } A container for pred and current values
256
Art of Multiprocessor Programming256 Using the Find Method Window window = find(head, key); Node pred = window.pred; curr = window.curr;
257
Art of Multiprocessor Programming257 Using the Find Method Window window = find(head, key); Node pred = window.pred; curr = window.curr; Find returns window
258
Art of Multiprocessor Programming258 Using the Find Method Window window = find(head, key); Node pred = window.pred; curr = window.curr; Extract pred and curr
259
Art of Multiprocessor Programming© Herlihy-Shavit 2007 259 The Find Method Window window = find(item); At some instant, predcurrsucc item or …
260
Art of Multiprocessor Programming© Herlihy-Shavit 2007 260 The Find Method Window window = find(item); At some instant, pred curr= null succ item not in list
261
Art of Multiprocessor Programming261 Remove public boolean remove(T item) { Boolean snip; while (true) { Window window = find(head, key); Node pred = window.pred, curr = window.curr; if (curr.key != key) { return false; } else { Node succ = curr.next.getReference(); snip = curr.next.compareAndSet(succ, succ, false true); if (!snip) continue; pred.next.compareAndSet(curr, succ, false, false); return true; }}}
262
Art of Multiprocessor Programming262 Remove public boolean remove(T item) { Boolean snip; while (true) { Window window = find(head, key); Node pred = window.pred, curr = window.curr; if (curr.key != key) { return false; } else { Node succ = curr.next.getReference(); snip = curr.next.compareAndSet (succ, succ, false, true); if (!snip) continue; pred.next.compareAndSet(curr, succ, false, false); return true; }}} Keep trying
263
Art of Multiprocessor Programming263 Remove public boolean remove(T item) { Boolean snip; while (true) { Window window = find(head, key); Node pred = window.pred, curr = window.curr; if (curr.key != key) { return false; } else { Node succ = curr.next.getReference(); snip = curr.next.compareAndSet (succ, succ, false, true); if (!snip) continue; pred.next.compareAndSet(curr, succ, false, false); return true; }}} Find neighbors
264
Art of Multiprocessor Programming264 Remove public boolean remove(T item) { Boolean snip; while (true) { Window window = find(head, key); Node pred = window.pred, curr = window.curr; if (curr.key != key) { return false; } else { Node succ = curr.next.getReference(); snip = curr.next.compareAndSet(succ, succ, false, true); if (!snip) continue; pred.next.compareAndSet(curr, succ, false, false); return true; }}} Shes not there …
265
Art of Multiprocessor Programming265 Remove public boolean remove(T item) { Boolean snip; while (true) { Window window = find(head, key); Node pred = window.pred, curr = window.curr; if (curr.key != key) { return false; } else { Node succ = curr.next.getReference(); snip = curr.next.compareAndSet(succ, succ, false, true); if (!snip) continue; pred.next.compareAndSet(curr, succ, false, false); return true; }}} Try to mark node as deleted
266
Art of Multiprocessor Programming266 Remove public boolean remove(T item) { Boolean snip; while (true) { Window window = find(head, key); Node pred = window.pred, curr = window.curr; if (curr.key != key) { return false; } else { Node succ = curr.next.getReference(); snip = curr.next.compareAndSet(succ, succ, false, true); if (!snip) continue; pred.next.compareAndSet(curr, succ, false, false); return true; }}} If it doesnt work, just retry, if it does, job essentially done
267
Art of Multiprocessor Programming267 Remove public boolean remove(T item) { Boolean snip; while (true) { Window window = find(head, key); Node pred = window.pred, curr = window.curr; if (curr.key != key) { return false; } else { Node succ = curr.next.getReference(); snip = curr.next.compareAndSet(succ, succ, false, true); if (!snip) continue; pred.next.compareAndSet(curr, succ, false, false); return true; }}} Try to advance reference (if we dont succeed, someone else did or will). a
268
Art of Multiprocessor Programming268 Add public boolean add(T item) { boolean splice; while (true) { Window window = find(head, key); Node pred = window.pred, curr = window.curr; if (curr.key == key) { return false; } else { Node node = new Node(item); node.next = new AtomicMarkableRef(curr, false); if (pred.next.compareAndSet(curr, node, false, false)) {return true;} }}}
269
Art of Multiprocessor Programming269 Add public boolean add(T item) { boolean splice; while (true) { Window window = find(head, key); Node pred = window.pred, curr = window.curr; if (curr.key == key) { return false; } else { Node node = new Node(item); node.next = new AtomicMarkableRef(curr, false); if (pred.next.compareAndSet(curr, node, false, false)) {return true;} }}} Item already there.
270
Art of Multiprocessor Programming270 Add public boolean add(T item) { boolean splice; while (true) { Window window = find(head, key); Node pred = window.pred, curr = window.curr; if (curr.key == key) { return false; } else { Node node = new Node(item); node.next = new AtomicMarkableRef(curr, false); if (pred.next.compareAndSet(curr, node, false, false)) {return true;} }}} create new node
271
Art of Multiprocessor Programming271 Add public boolean add(T item) { boolean splice; while (true) { Window window = find(head, key); Node pred = window.pred, curr = window.curr; if (curr.key == key) { return false; } else { Node node = new Node(item); node.next = new AtomicMarkableRef(curr, false); if (pred.next.compareAndSet(curr, node, false, false)) {return true;} }}} Install new node, else retry loop
272
Art of Multiprocessor Programming272 Wait-free Contains public boolean contains(T item) { boolean marked; int key = item.hashCode(); Node curr = head; while (curr.key < key) curr = curr.next; Node succ = curr.next.get(marked); return (curr.key == key && !marked[0]) }
273
Art of Multiprocessor Programming273 Wait-free Contains public boolean contains(T item) { boolean marked; int key = item.hashCode(); Node curr = head; while (curr.key < key) curr = curr.next; Node succ = curr.next.get(marked); return (curr.key == key && !marked[0]) } Only diff is that we get and check marked
274
Art of Multiprocessor Programming274 Lock-free Find public Window find(Node head, int key) { Node pred = null, curr = null, succ = null; boolean[] marked = {false}; boolean snip; retry: while (true) { pred = head; curr = pred.next.getReference(); while (true) { succ = curr.next.get(marked); while (marked[0]) { … } if (curr.key >= key) return new Window(pred, curr); pred = curr; curr = succ; } }}
275
Art of Multiprocessor Programming275 Lock-free Find public Window find(Node head, int key) { Node pred = null, curr = null, succ = null; boolean[] marked = {false}; boolean snip; retry: while (true) { pred = head; curr = pred.next.getReference(); while (true) { succ = curr.next.get(marked); while (marked[0]) { … } if (curr.key >= key) return new Window(pred, curr); pred = curr; curr = succ; } }} If list changes while traversed, start over
276
Art of Multiprocessor Programming276 public Window find(Node head, int key) { Node pred = null, curr = null, succ = null; boolean[] marked = {false}; boolean snip; retry: while (true) { pred = head; curr = pred.next.getReference(); while (true) { succ = curr.next.get(marked); while (marked[0]) { … } if (curr.key >= key) return new Window(pred, curr); pred = curr; curr = succ; } }} Lock-free Find Start looking from head
277
Art of Multiprocessor Programming277 public Window find(Node head, int key) { Node pred = null, curr = null, succ = null; boolean[] marked = {false}; boolean snip; retry: while (true) { pred = head; curr = pred.next.getReference(); while (true) { succ = curr.next.get(marked); while (marked[0]) { … } if (curr.key >= key) return new Window(pred, curr); pred = curr; curr = succ; } }} Lock-free Find Move down the list
278
Art of Multiprocessor Programming278 public Window find(Node head, int key) { Node pred = null, curr = null, succ = null; boolean[] marked = {false}; boolean snip; retry: while (true) { pred = head; curr = pred.next.getReference(); while (true) { succ = curr.next.get(marked); while (marked[0]) { … } if (curr.key >= key) return new Window(pred, curr); pred = curr; curr = succ; } }} Lock-free Find Get ref to successor and current deleted bit
279
Art of Multiprocessor Programming279 public Window find(Node head, int key) { Node pred = null, curr = null, succ = null; boolean[] marked = {false}; boolean snip; retry: while (true) { pred = head; curr = pred.next.getReference(); while (true) { succ = curr.next.get(marked); while (marked[0]) { … } if (curr.key >= key) return new Window(pred, curr); pred = curr; curr = succ; } }} Lock-free Find Try to remove deleted nodes in path…code details soon
280
Art of Multiprocessor Programming280 public Window find(Node head, int key) { Node pred = null, curr = null, succ = null; boolean[] marked = {false}; boolean snip; retry: while (true) { pred = head; curr = pred.next.getReference(); while (true) { succ = curr.next.get(marked); while (marked[0]) { … } if (curr.key >= key) return new Window(pred, curr); pred = curr; curr = succ; } }} Lock-free Find If curr key that is greater or equal, return pred and curr
281
Art of Multiprocessor Programming281 public Window find(Node head, int key) { Node pred = null, curr = null, succ = null; boolean[] marked = {false}; boolean snip; retry: while (true) { pred = head; curr = pred.next.getReference(); while (true) { succ = curr.next.get(marked); while (marked[0]) { … } if (curr.key >= key) return new Window(pred, curr); pred = curr; curr = succ; } }} Lock-free Find Otherwise advance window and loop again
282
Art of Multiprocessor Programming282 Lock-free Find retry: while (true) { … while (marked[0]) { snip = pred.next.compareAndSet(curr, succ, false, false); if (!snip) continue retry; curr = succ; succ = curr.next.get(marked); } …
283
retry: while (true) { … while (marked[0]) { snip = pred.next.compareAndSet(curr, succ, false, false); if (!snip) continue retry; curr = succ; succ = curr.next.get(marked); } … Art of Multiprocessor Programming283 Lock-free Find Try to snip out node
284
retry: while (true) { … while (marked[0]) { snip = pred.next.compareAndSet(curr, succ, false, false); if (!snip) continue retry; curr = succ; succ = curr.next.get(marked); } … Art of Multiprocessor Programming284 Lock-free Find if predecessors next field changed, retry whole traversal
285
Art of Multiprocessor Programming285 Lock-free Find retry: while (true) { … while (marked[0]) { snip = pred.next.compareAndSet(curr, succ, false, false); if (!snip) continue retry; curr = succ; succ = curr.next.get(marked); } … Otherwise move on to check if next node deleted
286
Performance Different list-based set implementaions 16-node machine Vary percentage of contains() calls Art of Multiprocessor Programming286
287
Art of Multiprocessor Programming287 High Contains Ratio Lock-free Lazy list Coarse Grained Fine Lock-coupling
288
Art of Multiprocessor Programming288 Low Contains Ratio
289
Art of Multiprocessor Programming289 As Contains Ratio Increases % Contains()
290
Art of Multiprocessor Programming290 Summary Coarse-grained locking Fine-grained locking Optimistic synchronization Lazy synchronization Lock-free synchronization
291
Art of Multiprocessor Programming291 To Lock or Not to Lock Locking vs. Non-blocking: –Extremist views on both sides The answer: nobler to compromise –Example: Lazy list combines blocking add() and remove() and a wait-free contains() –Remember: Blocking/non-blocking is a property of a method
292
Art of Multiprocessor Programming292 This work is licensed under a Creative Commons Attribution- ShareAlike 2.5 License.Creative Commons Attribution- ShareAlike 2.5 License You are free: –to Share to copy, distribute and transmit the work –to Remix to adapt the work Under the following conditions: –Attribution. You must attribute the work to The Art of Multiprocessor Programming (but not in any way that suggests that the authors endorse you or your use of the work). –Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under the same, similar or a compatible license. For any reuse or distribution, you must make clear to others the license terms of this work. The best way to do this is with a link to –http://creativecommons.org/licenses/by-sa/3.0/. Any of the above conditions can be waived if you get permission from the copyright holder. Nothing in this license impairs or restricts the author's moral rights.
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.