Presentation is loading. Please wait.

Presentation is loading. Please wait.

Concurrent Linked Lists and Linearizability Proofs Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit Modified.

Similar presentations


Presentation on theme: "Concurrent Linked Lists and Linearizability Proofs Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit Modified."— Presentation transcript:

1 Concurrent Linked Lists and Linearizability Proofs Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit Modified by Pavol Černý, Programming Paradigms for Concurrency, Fall 2010, IST Austria

2 Art of Multiprocessor Programming2 First: Issues in Linearizability Q1: Are linearizability proofs composable? Q2: Linearizability vs (strict) serializability

3 Art of Multiprocessor Programming 3 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

4 Art of Multiprocessor Programming 4 Linearizability Equivalently: Each method should –take effect instantaneously –between invocation and response events –object is correct if this “ sequential ” behavior is correct

5 Art of Multiprocessor Programming 5 Composability Theorem History H is linearizable if and only if –For every object x –H|x is linearizable (proof on the board)

6 Art of Multiprocessor Programming 6 Linearizability vs (strict) serializability Serializability: A history is serializable if it is equivalent to one in which transactions appear to execute sequentially (without interleaving) Strict serializability: In addition, the order of transactions in the sequential history respects precedence order from the interleaved history Linearizability: A special case of strict serializability, where each “transaction” (method) accesses a single object (Strict) serializability non-local.

7 Art of Multiprocessor Programming7 Today: Concurrent Objects Adding threads should not lower throughput –Contention effects Should increase throughput –Not possible if inherently sequential –Surprising things are parallelizable

8 Art of Multiprocessor Programming8 Coarse-Grained Synchronization Each method locks the object –Avoid contention using queue locks

9 Art of Multiprocessor Programming9 Coarse-Grained Synchronization Each method locks the object –Avoid contention using queue locks –Easy to reason about In simple cases

10 Art of Multiprocessor Programming10 Coarse-Grained Synchronization Each method locks the object –Avoid contention using queue locks –Easy to reason about In simple cases So, are we done?

11 Art of Multiprocessor Programming11 Coarse-Grained Synchronization Sequential bottleneck –Threads “stand in line”

12 Art of Multiprocessor Programming12 Coarse-Grained Synchronization Sequential bottleneck –Threads “stand in line” Adding more threads –Does not improve throughput –Struggle to keep it from getting worse

13 Art of Multiprocessor Programming13 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 …

14 Art of Multiprocessor Programming14 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 For us: example for proofs of linearizability

15 Art of Multiprocessor Programming15 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

16 Art of Multiprocessor Programming16 List-Based Sets public interface Set { public boolean add(T x); public boolean remove(T x); public boolean contains(T x); }

17 Art of Multiprocessor Programming17 List Node public class Node { public T item; public int key; public Node next; }

18 Art of Multiprocessor Programming18 List Node public class Node { public T item; public int key; public Node next; } item of interest

19 Art of Multiprocessor Programming19 List Node public class Node { public T item; public int key; public Node next; } Usually hash code

20 Art of Multiprocessor Programming20 List Node public class Node { public T item; public int key; public Node next; } Reference to next node

21 Art of Multiprocessor Programming21 The List-Based Set abc Sorted with Sentinel nodes (min & max possible keys) -∞ +∞

22 Art of Multiprocessor Programming22 Invariants Sentinel nodes –tail reachable from head Sorted No duplicates

23 Art of Multiprocessor Programming23 Sequential List Based Set a c d a b c Add() Remove()

24 Art of Multiprocessor Programming24 Sequential List Based Set a c d b a b c Add() Remove()

25 Art of Multiprocessor Programming25 Coarse Grained Locking a b d

26 Art of Multiprocessor Programming26 Coarse Grained Locking a b d c

27 Art of Multiprocessor Programming27 honk! Coarse Grained Locking a b d c Simple but hotspot + bottleneck honk!

28 Art of Multiprocessor Programming28 Coarse-Grained Locking Easy, same as synchronized methods –“One lock to rule them all …”

29 Art of Multiprocessor Programming29 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

30 Art of Multiprocessor Programming30 Fine-grained Locking Requires careful thought Split object into pieces –Each piece has own lock –Methods that work on disjoint pieces need not exclude each other

31 Art of Multiprocessor Programming31 Hand-over-Hand locking abc

32 Art of Multiprocessor Programming32 Hand-over-Hand locking abc

33 Art of Multiprocessor Programming33 Hand-over-Hand locking abc

34 Art of Multiprocessor Programming34 Hand-over-Hand locking abc

35 Art of Multiprocessor Programming35 Hand-over-Hand locking abc

36 Art of Multiprocessor Programming36 Removing a Node abcd remove(b)

37 Art of Multiprocessor Programming37 Removing a Node abcd remove(b)

38 Art of Multiprocessor Programming38 Removing a Node abcd remove(b)

39 Art of Multiprocessor Programming39 Removing a Node abcd remove(b)

40 Art of Multiprocessor Programming40 Removing a Node abcd remove(b)

41 Art of Multiprocessor Programming41 Removing a Node acd remove(b) Why hold 2 locks?

42 Art of Multiprocessor Programming42 Remove method public boolean remove(Item item) { int key = item.hashCode(); Node pred, curr; try { … } finally { curr.unlock(); pred.unlock(); }}

43 Art of Multiprocessor Programming43 Remove method public boolean remove(Item item) { int key = item.hashCode(); Node pred, curr; try { … } finally { curr.unlock(); pred.unlock(); }} Key used to order node

44 Art of Multiprocessor Programming44 Remove method public boolean remove(Item item) { int key = item.hashCode(); Node pred, curr; try { … } finally { currNode.unlock(); predNode.unlock(); }} Predecessor and current nodes

45 Art of Multiprocessor Programming45 Remove method public boolean remove(Item item) { int key = item.hashCode(); Node pred, curr; try { … } finally { curr.unlock(); pred.unlock(); }} Make sure locks released

46 Art of Multiprocessor Programming46 Remove method public boolean remove(Item item) { int key = item.hashCode(); Node pred, curr; try { … } finally { curr.unlock(); pred.unlock(); }} Everything else

47 Art of Multiprocessor Programming47 Remove method try { pred = this.head; pred.lock(); curr = pred.next; curr.lock(); … } finally { … }

48 Art of Multiprocessor Programming48 Remove method try { pred = this.head; pred.lock(); curr = pred.next; curr.lock(); … } finally { … } lock pred == head

49 Art of Multiprocessor Programming49 Remove method try { pred = this.head; pred.lock(); curr = pred.next; curr.lock(); … } finally { … } Lock current

50 Art of Multiprocessor Programming50 Remove method try { pred = this.head; pred.lock(); curr = pred.next; curr.lock(); … } finally { … } Traversing list

51 Art of Multiprocessor Programming51 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;

52 Art of Multiprocessor Programming52 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; Search key range

53 Art of Multiprocessor Programming53 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; At start of each loop: curr and pred locked

54 Art of Multiprocessor Programming54 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; If item found, remove node

55 Art of Multiprocessor Programming55 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; If node found, remove it

56 Art of Multiprocessor Programming56 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; Unlock predecessor

57 Art of Multiprocessor Programming57 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; Only one node locked!

58 Art of Multiprocessor Programming58 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; demote current

59 Art of Multiprocessor Programming59 Remove: searching 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; Find and lock new current

60 Art of Multiprocessor Programming60 Remove: searching 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; Lock invariant restored

61 Art of Multiprocessor Programming61 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

62 Art of Multiprocessor Programming62 Adding Nodes To add node e –Must lock predecessor –Must lock successor Neither can be deleted

63 Proving linearizability Rely-guarantee approach –Vafeiadis, Herlihy, Hoare, Shapiro 2006 Reduction approach –Elmas, Qadeer, Tasiran 2009 Art of Multiprocessor Programming63

64 Rely-guarantee Sequential programs: {p}C{q} -- Hoare logic Parallel programs: C models (p,R,G,q) Art of Multiprocessor Programming64

65 Rely-guarantee Parallel programs: C models (p,R,G,q) p – precondition – state predicate q – postcondition – transition predicate R – rely conditions – what we tolearte from other threads G – guarantee conditions – we do our part Art of Multiprocessor Programming65

66 Rely-guarantee Rules: {p}C{q} in Hoare logic models (p,R,G,q) Art of Multiprocessor Programming66 C1 models (p1,R,G,q1) C2 models (p2,R,G,q2) q1 -> p2 C1;C2 models (p1,R,G,(q1;R*;q2))

67 Rely-guarantee Art of Multiprocessor Programming67 C1 models (p1,R1,G1,q1) G2 -> R1 C2 models (p2,R2,G2,q2) G1 -> R2 C1 || C2 models (p1&p2,R1&R2,G1 or G2,q) where q is q1;(R1&R2)*;q2 or q1;(R1&R2)*;q2

68 68 Example: increment local int t; acquire (lock); t := x; t := t + 1; x := t; release (lock); global int x; x := 0; || assert (x == 2); local int t; acquire (lock); t := x; t := t + 1; x := t; release (lock);

69 69 Example: increment Rely condition R: L.owner = self -> x’=x Guarantee condition G: L.owner ≠ self -> x’=x We prove: P models (true,R,G,x’=x+1) P1||P2 models (true,R,G,x’=x+2) (proofs on the board)

70 Proving remove Art of Multiprocessor Programming70 AbsRemove(e): { AbsResult = (e in Abs); Abs = Abs – {e}} Strategy: 1. find linearization points 2. insert AbsRemove 3. prove that AbsResult = Result

71 71 Reduction proofs inc (): local int t; acquire (lock); t := x; t := t + 1; x := t; release(lock); Main: x := 0; inc(); || inc(); assert (x == 2); Slides adapted from Tayfun Elmas.

72 Art of Multiprocessor Programming72 Proof by reduction inc (): int t; acquire (lock); t := x; t := t + 1; x := t; release(lock); R B B B L inc (): int t; acquire (lock); t := x; t := t + 1; x := t; release(lock); inc (): x := x + 1; havoc t; REDUCE-SEQUENTIAL ABSTRACT

73 73 Reduction  ;  ;  ...   1   2 ...   n     ...  right-mover: For each execution: Exist equivalent executions: 73...     1   2 ...   n   ......   1     2 ...   n   .................   1   2 ...     n   ...  ; 

74 Art of Multiprocessor Programming 74 Static mover check - 1 Right mover: Commutes to the right of any other action run by a different thread Static right-mover check for  : For every action  in program: (run by different thread) ;;  ;  abstracted by

75 Art of Multiprocessor Programming75 Static mover check - 2 Static right-mover check between  and  : Simple cases Mover check passes:  and  access different variables Fails:  and  1) simultaneously enabled and 2) perform conflicting accesses to a variable 75 ;;  ;  abstracted by

76 Abstraction rule: –Replace  with  if: Art of Multiprocessor Programming76 Abstraction   abstracted by 76 Going wrong more often is sound for assertion checking Forall : error s1s1 s1s1 1. If then exists s1s1 2. If then exists s2s2 s1s1 s2s2 or error s1s1 s1s1     

77 Art of Multiprocessor Programming77 Drawbacks of fine-grained locking lists Better than coarse-grained lock –Threads can traverse in parallel Still not ideal –Long chain of acquire/release –Inefficient


Download ppt "Concurrent Linked Lists and Linearizability Proofs Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit Modified."

Similar presentations


Ads by Google