Presentation is loading. Please wait.

Presentation is loading. Please wait.

Art of Multiprocessor Programming 1 Universality of Consensus Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit.

Similar presentations


Presentation on theme: "Art of Multiprocessor Programming 1 Universality of Consensus Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit."— Presentation transcript:

1 Art of Multiprocessor Programming 1 Universality of Consensus 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 Turing Computability A mathematical model of computation Computable = Computable on a T-Machine 011010 1

3 Art of Multiprocessor Programming 3 Shared-Memory Computability Model of asynchronous concurrent computation Computable = Wait-free/Lock-free computable on a multiprocessor cache shared memory cache

4 Art of Multiprocessor Programming 4 Consensus Hierarchy 1 Read/Write Registers, Snapshots… 2 getAndSet, getAndIncrement, … ∞ compareAndSet,…......

5 Art of Multiprocessor Programming 5 Who Implements Whom? 1 Read/Write Registers, Snapshots… 2 getAndSet, getAndIncrement, … ∞ compareAndSet,…...... no

6 Art of Multiprocessor Programming 6 Hypothesis 1 Read/Write Registers, Snapshots… 2 getAndSet, getAndIncrement, … ∞ compareAndSet,…...... yes?

7 Art of Multiprocessor Programming 7 Theorem: Universality Consensus is universal From n-thread consensus build a –Wait-free –Linearizable –n-threaded implementation –Of any sequentially specified object

8 Art of Multiprocessor Programming 8 Proof Outline A universal construction –From n-consensus objects –And atomic registers Any wait-free linearizable object –Not a practical construction –But we know where to start looking …

9 Art of Multiprocessor Programming 9 Like a Turing Machine This construction –Illustrates what needs to be done –Optimization fodder Correctness, not efficiency

10 Art of Multiprocessor Programming 10 A Generic Sequential Object public interface SeqObject { public abstract Response apply(Invocation invoc); }

11 Art of Multiprocessor Programming 11 A Generic Sequential Object public interface SeqObject { public abstract Response apply(Invocation invoc); } Push:5, Pop:null

12 Art of Multiprocessor Programming 12 Invocation public class Invoc { public String method; public Object[] args; }

13 Art of Multiprocessor Programming 13 Invocation public class Invoc { public String method; public Object[] args; } Method name

14 Art of Multiprocessor Programming 14 Invocation public class Invoc { public String method; public Object[] args; } Arguments

15 Art of Multiprocessor Programming 15 A Generic Sequential Object public interface SeqObject { public abstract Response apply(Invocation invoc); }

16 Art of Multiprocessor Programming 16 A Generic Sequential Object public interface SeqObject { public abstract Response apply(Invocation invoc); } OK, 4

17 Art of Multiprocessor Programming 17 Response public class Response { public Object value; }

18 Art of Multiprocessor Programming 18 Response public class Response { public Object value; } Return value

19 Art of Multiprocessor Programming 19 Universal Concurrent Object public interface SeqObject { public abstract Response apply(Invocation invoc); } A universal concurrent object is linearizable to the generic sequential object

20 Art of Multiprocessor Programming 20 Start with Lock-Free Universal Construction First Lock-free: infinitely often some method call finishes. Then Wait-Free: each method call takes a finite number of steps to finish

21 Art of Multiprocessor Programming 21 Naïve Idea Consensus object stores reference to cell with current state Each thread creates new cell –computes outcome, –tries to switch pointer to its outcome Sadly, no … –consensus objects can be used once only

22 Art of Multiprocessor Programming 22 Naïve Idea enq deq

23 Art of Multiprocessor Programming 23 head Naïve Idea deq Concurrent Object enq ? Decide which to apply using consensus No good. Each thread can use consensus object only once

24 Art of Multiprocessor Programming 24 Once is not Enough? public decide(object value) { propose(value); Ball ball = this.queue.deq(); if (ball == Ball.RED) return proposed[i]; else return proposed[1-i]; } Solved one-shot 2-consensus. Not clear how to reuse or reread … Queue based consensus

25 Art of Multiprocessor Programming 25 Improved Idea: Linked-List Representation enq tail deq Each node contains a fresh consensus object used to decide on next operation

26 Art of Multiprocessor Programming 26 Universal Construction Object represented as –Initial Object State –A Log: a linked list of the method calls

27 Art of Multiprocessor Programming 27 Universal Construction Object represented as –Initial Object State –A Log: a linked list of the method calls New method call –Find end of list –Atomically append call –Compute response by replaying log

28 Art of Multiprocessor Programming 28 Basic Idea Use one-time consensus object to decide next pointer All threads update actual next pointer based on decision –OK because they all write the same value Challenges –Lock-free means we need to worry what happens if a thread stops in the middle

29 Art of Multiprocessor Programming 29 public class Node implements java.lang.Comparable { public Invoc invoc; public Consensus decideNext; public Node next; public int seq; public Node(Invoc invoc) { invoc = invoc; decideNext = new Consensus () seq = 0; } Basic Data Structures

30 Art of Multiprocessor Programming 30 public class Node implements java.lang.Comparable { public Invoc invoc; public Consensus decideNext; public Node next; public int seq; public Node(Invoc invoc) { invoc = invoc; decideNext = new Consensus () seq = 0; } Basic Data Structures Standard interface for class whose objects are totally ordered

31 Art of Multiprocessor Programming 31 public class Node implements java.lang.Comparable { public Invoc invoc; public Consensus decideNext; public Node next; public int seq; public Node(Invoc invoc) { invoc = invoc; decideNext = new Consensus () seq = 0; } Basic Data Structures the invocation

32 Art of Multiprocessor Programming 32 public class Node implements java.lang.Comparable { public Invoc invoc; public Consensus decideNext; public Node next; public int seq; public Node(Invoc invoc) { invoc = invoc; decideNext = new Consensus () seq = 0; } Basic Data Structures Decide on next node (next method applied to object)

33 Art of Multiprocessor Programming 33 public class Node implements java.lang.Comparable { public Invoc invoc; public Consensus decideNext; public Node next; public int seq; public Node(Invoc invoc) { invoc = invoc; decideNext = new Consensus () seq = 0; } Basic Data Structures Traversable pointer to next node (needed because you cannot repeatedly read a consensus object)

34 Art of Multiprocessor Programming 34 public class Node implements java.lang.Comparable { public Invoc invoc; public Consensus decideNext; public Node next; public int seq; public Node(Invoc invoc) { invoc = invoc; decideNext = new Consensus () seq = 0; } Basic Data Structures Seq number

35 Art of Multiprocessor Programming 35 public class Node implements java.lang.Comparable { public Invoc invoc; public Consensus decideNext; public Node next; public int seq; public Node(Invoc invoc) { invoc = invoc; decideNext = new Consensus () seq = 0; } Basic Data Structures Create new node for this method invocation

36 Art of Multiprocessor Programming 36 Universal Object head 123 decideNext (Consensus Object) Ptr to cell w/highest Seq Num Seq number, Invoc tail node next 4

37 Art of Multiprocessor Programming 37 Universal Object head 123 All threads repeatedly modify head…back to where we started? tail node 4

38 Art of Multiprocessor Programming 38 … The Solution head 123 tail node i 4 Make head an array Ptr to node at front Thread i updates location i Threads find head by finding Max of nodes pointed to by head array

39 Art of Multiprocessor Programming 39 Universal Object public class Universal { private Node[] head; private Node tail = new Node(); tail.seq = 1; for (int j=0; j < n; j++){ head[j] = tail }

40 Art of Multiprocessor Programming 40 Universal Object public class Universal { private Node[] head; private Node tail = new Node(); tail.seq = 1; for (int j=0; j < n; j++){ head[j] = tail } Head Pointers Array

41 Art of Multiprocessor Programming 41 Universal Object public class Universal { private Node[] head; private Node tail = new Node(); tail.seq = 1; for (int j=0; j < n; j++){ head[j] = tail } Tail is a sentinel node with sequence number 1

42 Art of Multiprocessor Programming 42 Universal Object public class Universal { private Node[] head; private Node tail = new Node(); tail.seq = 1; for (int j=0; j < n; j++){ head[j] = tail } Tail is a sentinel node with sequence number 1

43 Art of Multiprocessor Programming 43 Universal Object public class Universal { private Node[] head; private Node tail = new Node(); tail.seq = 1; for (int j=0; j < n; j++){ head[j] = tail } Initially head points to tail

44 Art of Multiprocessor Programming 44 public static Node max(Node[] array) { Node max = array[0]; for (int i = 1; i < array.length; i++) if (max.seq < array[i].seq) max = array[i]; return max; } Find Max Head Value

45 Art of Multiprocessor Programming 45 public static Node max(Node[] array) { Node max = array[0]; for (int i = 0; i < array.length; i++) if (max.seq < array[i].seq) max = array[i]; return max; } Find Max Head Value Traverse the array

46 Art of Multiprocessor Programming 46 public static Node max(Node[] array) { Node max = array[0]; for (int i = 0; i < array.length; i++) if (max.seq < array[i].seq) max = array[i]; return max; } Find Max Head Value Compare the seq nums of nodes pointed to by the array

47 Art of Multiprocessor Programming 47 public static Node max(Node[] array) { Node max = array[0]; for (int i = 0; i < array.length; i++) if (max.seq < array[i].seq) max = array[i]; return max; } Find Max Head Value Compare the seq nums of nodes pointed to by the array

48 Art of Multiprocessor Programming 48 Universal Application Part I public Response apply(Invoc invoc) { int i = ThreadID.get(); Node prefer = new node(invoc); while (prefer.seq == 0) { Node before = Node.max(head); Node after = before.decideNext.decide(prefer); before.next = after; after.seq = before.seq + 1; head[i] = after; } …

49 Art of Multiprocessor Programming 49 Universal Application Part I public Response apply(Invoc invoc) { int i = ThreadID.get(); Node prefer = new node(invoc); while (prefer.seq == 0) { Node before = Node.max(head); Node after = before.decideNext.decide(prefer); before.next = after; after.seq = before.seq + 1; head[i] = after; } … Apply will have invocation as input and return the appropriate response

50 Art of Multiprocessor Programming 50 Universal Application Part I public Response apply(Invoc invoc) { int i = ThreadID.get(); Node prefer = new node(invoc); while (prefer.seq == 0) { Node before = Node.max(head); Node after = before.decideNext.decide(prefer); before.next = after; after.seq = before.seq + 1; head[i] = after; } … My id

51 Art of Multiprocessor Programming 51 Universal Application Part I public Response apply(Invoc invoc) { int i = ThreadID.get(); Node prefer = new node(invoc); while (prefer.seq == 0) { Node before = Node.max(head); Node after = before.decideNext.decide(prefer); before.next = after; after.seq = before.seq + 1; head[i] = after; } … My method call

52 Art of Multiprocessor Programming 52 Universal Application Part I public Response apply(Invoc invoc) { int i = ThreadID.get(); Node prefer = new node(invoc); while (prefer.seq == 0) { Node before = Node.max(head); Node after = before.decideNext.decide(prefer); before.next = after; after.seq = before.seq + 1; head[i] = after; } … As long as I have not been threaded into list

53 Art of Multiprocessor Programming 53 Universal Application Part I public Response apply(Invoc invoc) { int i = ThreadID.get(); Node prefer = new node(invoc); while (prefer.seq == 0) { Node before = Node.max(head); Node after = before.decideNext.decide(prefer); before.next = after; after.seq = before.seq + 1; head[i] = after; } … Head of list to which we will try to append

54 Art of Multiprocessor Programming 54 Universal Application Part I public Response apply(Invoc invoc) { int i = ThreadID.get(); Node prefer = new node(invoc); while (prefer.seq == 0) { Node before = Node.max(head); Node after = before.decideNext.decide(prefer); before.next = after; after.seq = before.seq + 1; head[i] = after; } Propose next node

55 Art of Multiprocessor Programming 55 Universal Application public Response apply(Invoc invoc) { int i = ThreadID.get(); Node prefer = new node(invoc); while (prefer.seq == 0) { Node before = Node.max(head); Node after = before.decideNext.decide(prefer); before.next = after; after.seq = before.seq + 1; head[i] = after; } Set next field to consensus winner

56 Art of Multiprocessor Programming 56 Universal Application Part I public Response apply(Invoc invoc) { int i = ThreadID.get(); Node prefer = new node(invoc); while (prefer.seq == 0) { Node before = Node.max(head); Node after = before.decideNext.decide(prefer); before.next = after; after.seq = before.seq + 1; head[i] = after; } … Set seq number (indicating node was appended)

57 Art of Multiprocessor Programming 57 Universal Application Part I public Response apply(Invoc invoc) { int i = ThreadID.get(); Node prefer = new node(invoc); while (prefer.seq == 0) { Node before = Node.max(head); Node after = before.decideNext.decide(prefer); before.next = after; after.seq = before.seq + 1; head[i] = after; } … add to head array so new head will be found

58 Art of Multiprocessor Programming 58 Part 2 – Compute Response nullenq( ) tail Red’s method call … deq() enq( ) Return Private copy of object

59 Art of Multiprocessor Programming 59 Universal Application Part 2... //compute my response SeqObject MyObject = new SeqObject(); current = tail.next; while (current != prefer){ MyObject.apply(current.invoc); current = current.next; } return MyObject.apply(current.invoc); }

60 Art of Multiprocessor Programming 60 Universal Application Part II... //compute my response SeqObject MyObject = new SeqObject(); current = tail.next; while (current != prefer){ MyObject.apply(current.invoc); current = current.next; } return MyObject.apply(current.invoc); } Compute result by sequentially applying method calls in list to a private copy

61 Art of Multiprocessor Programming 61 Universal Application Part II... //compute my response SeqObject MyObject = new SeqObject(); current = tail.next; while (current != prefer){ MyObject.apply(current.invoc); current = current.next; } return MyObject.apply(current.invoc); } Start with copy of sequential object

62 Art of Multiprocessor Programming 62 Universal Application Part II... //compute my response SeqObject MyObject = new SeqObject(); current = tail.next; while (current != prefer){ MyObject.apply(current.invoc); current = current.next; } return MyObject.apply(current.invoc); } new method call appended after tail

63 Art of Multiprocessor Programming 63 Universal Application Part II... //compute my response SeqObject MyObject = new SeqObject(); current = tail.next; while (current != prefer){ MyObject.apply(current.invoc); current = current.next; } return MyObject.apply(current.invoc); } While my method call not linked …

64 Art of Multiprocessor Programming 64 Universal Application Part II... //compute my response SeqObject MyObject = new SeqObject(); current = tail.next; while (current != prefer){ MyObject.apply(current.invoc); current = current.next; } return MyObject.apply(current.invoc); } Apply current node’s method

65 Art of Multiprocessor Programming 65 Universal Application Part II... //compute my response SeqObject MyObject = new SeqObject(); current = tail.next; while (current != prefer){ MyObject.apply(current.invoc); current = current.next; } return MyObject.apply(current.invoc); } Return result after my method call applied

66 Art of Multiprocessor Programming 66 Correctness List defines linearized sequential history Thread returns its response based on list order

67 Art of Multiprocessor Programming 67 Lock-freedom Lock-free because –A thread moves forward in list –Can repeatedly fail to win consensus on “real” head only if another succeeds –Consensus winner adds node and completes within a finite number of steps

68 Art of Multiprocessor Programming 68 Wait-free Construction Lock-free construction + announce array Stores (pointer to) node in announce –If a thread doesn’t append its node –Another thread will see it in array and help append it

69 Art of Multiprocessor Programming 69 Helping “Announcing” my intention –Guarantees progress –Even if the scheduler hates me –My method call will complete Makes protocol wait-free Otherwise starvation possible

70 Art of Multiprocessor Programming 70 … … Wait-free Construction head 123 tail i 4 announce Ptr to cell thread i wants to append i

71 Art of Multiprocessor Programming 71 public class Universal { private Node[] announce; private Node[] head; private Node tail = new node(); tail.seq = 1; for (int j=0; j < n; j++){ head[j] = tail; announce[j] = tail }; The Announce Array

72 Art of Multiprocessor Programming 72 public class Universal { private Node[] announce; private Node[] head; private Node tail = new node(); tail.seq = 1; for (int j=0; j < n; j++){ head[j] = tail; announce[j] = tail }; The Announce Array Announce array

73 Art of Multiprocessor Programming 73 public class Universal { private Node[] announce; private Node[] head; private Node tail = new node(); tail.seq = 1; for (int j=0; j < n; j++){ head[j] = tail; announce[j] = tail }; The Announce Array All entries initially point to tail

74 Art of Multiprocessor Programming 74 public Response apply(Invoc invoc) { int i = ThreadID.get(); announce[i] = new Node(invoc); head[i] = Node.max(head); while (announce[i].seq == 0) { … // while node not appended to list … } A Cry For Help

75 Art of Multiprocessor Programming 75 public Response apply(Invoc invoc) { int i = ThreadID.get(); announce[i] = new Node(invoc); head[i] = Node.max(head); while (announce[i].seq == 0) { … // while node not appended to list … } A Cry For Help Announce new method call, asking help from others

76 Art of Multiprocessor Programming 76 public Response apply(Invoc invoc) { int i = ThreadID.get(); announce[i] = new Node(invoc); head[i] = Node.max(head); while (announce[i].seq == 0) { … // while node not appended to list … } A Cry For Help Look for end of list

77 Art of Multiprocessor Programming 77 public Response apply(Invoc invoc) { int i = ThreadID.get(); announce[i] = new Node(invoc); head[i] = Node.max(head); while (announce[i].seq == 0) { … // while node not appended to list … } A Cry For Help Main loop, while node not appended (either by me or helper)

78 Art of Multiprocessor Programming 78 Main Loop Non-zero sequence number indicates success Thread keeps helping append nodes Until its own node is appended

79 Art of Multiprocessor Programming 79 while (announce[i].seq == 0) { Node before = head[i]; Node help = announce[(before.seq + 1 % n)]; if (help.seq == 0) prefer = help; else prefer = announce[i]; … Main Loop

80 Art of Multiprocessor Programming 80 while (announce[i].seq == 0) { Node before = head[i]; Node help = announce[(before.seq + 1 % n)]; if (help.seq == 0) prefer = help; else prefer = announce[i]; … Main Loop Keep trying until my cell gets a sequence number

81 Art of Multiprocessor Programming 81 while (announce[i].seq == 0) { Node before = head[i]; Node help = announce[(before.seq + 1 % n)]; if (help.seq == 0) prefer = help; else prefer = announce[i]; … Main Loop Possible end of list

82 Art of Multiprocessor Programming 82 while (announce[i].seq == 0) { Node before = head[i]; Node help = announce[(before.seq + 1 % n)]; if (help.seq == 0) prefer = help; else prefer = announce[i]; … Main Loop Whom do I help?

83 Art of Multiprocessor Programming 83 Altruism Choose a thread to “help” If that thread needs help –Try to append its node –Otherwise append your own Worst case –Everyone tries to help same pitiful loser –Someone succeeds

84 Art of Multiprocessor Programming 84 Help! When last node in list has sequence number k All threads check … –Whether thread k+1 mod n wants help –If so, try to append her node first

85 Art of Multiprocessor Programming 85 Help! First time after thread k+1 announces –No guarantees After n more nodes appended –Everyone sees that thread k+1 wants help –Everyone tries to append that node –Someone succeeds

86 Art of Multiprocessor Programming 86 Sliding Window Lemma After thread A announces its node No more than n other calls –Can start and finish –Without appending A’s node

87 Art of Multiprocessor Programming 87 Helping head 1 2 3 Max head +1 = N+4 N+2 N+3 … announce Thread 4: Help me! 4 So all see and help append 4 tail

88 Art of Multiprocessor Programming 88 The Sliding Help Window head 1 2 3 N+2 N+3 … announce 4 tail Help 3 Help 4 3

89 Art of Multiprocessor Programming 89 while (announce[i].seq == 0) { Node before = head[i]; Node help = announce[(before.seq + 1 % n)]; if (help.seq == 0) prefer = help; else prefer = announce[i]; … Sliding Help Window In each main loop iteration pick another thread to help

90 Art of Multiprocessor Programming 90 while (announce[i].seq == 0) { Node before = head[i]; Node help = announce[(before.seq + 1 % n)]; if (help.seq == 0) prefer = help; else prefer = announce[i]; … Sliding Help Window Help if help required, but otherwise it’s all about me!

91 Art of Multiprocessor Programming 91 Rest is Same as Lock-free while (prefer.seq == 0) { … Node after = before.decideNext.decide(prefer); before.next = after; after.seq = before.seq + 1; head[i] = after; }

92 Art of Multiprocessor Programming 92 Rest is Same as Lock-free while (prefer.seq == 0) { … Node after = before.decideNext.decide(prefer); before.next = after; after.seq = before.seq + 1; head[i] = after; } Decide next node to be appended

93 Art of Multiprocessor Programming 93 Rest is Same as Lock-free while (prefer.seq == 0) { … Node after = before.decideNext.decide(prefer); before.next = after; after.seq = before.seq + 1; head[i] = after; } Update next based on decision

94 Art of Multiprocessor Programming 94 Rest is Same as Lock-free while (prefer.seq == 0) { … Node after = before.decideNext.decide(prefer); before.next = after; after.seq = before.seq + 1; head[i] = after; } Tell world that node is appended

95 Art of Multiprocessor Programming 95 Finishing the Job Once thread’s node is linked The rest is again the same as in lock- free alg Compute the result by sequentially applying the method calls in the list to a private copy of the object starting from the initial state

96 Art of Multiprocessor Programming 96 Then Same Part II... //compute my response SeqObject MyObject = new SeqObject(); current = tail.next; while (current != prefer){ MyObject.apply(current.invoc); current = current.next; } return MyObject.apply(current.invoc); }

97 Art of Multiprocessor Programming 97 Universal Application Part II... //compute my response SeqObject MyObject = new SeqObject(); current = tail.next; while (current != prefer){ MyObject.apply(current.invoc); current = current.next; } return MyObject.apply(current.invoc); } Return result after applying my method

98 Art of Multiprocessor Programming 98 Shared-Memory Computability Wait-free/Lock-free computable = Solving n-consensus 10011 Universal Object

99 Art of Multiprocessor Programming 99 On Older Architectures IBM 360 –testAndSet (getAndSet) NYU UltraComputer –getAndAdd Neither universal –Except for 2 threads

100 Art of Multiprocessor Programming 100 On Newer Architectures Intel x86, Itanium, SPARC –compareAndSet Alpha AXP, PowerPC –Load-locked/store-conditional All universal –For any number of threads Trend is clear …

101 Art of Multiprocessor Programming 101 Practical Implications Any architecture that does not provide a universal primitive has inherent limitations You cannot avoid locking for concurrent data structures …


Download ppt "Art of Multiprocessor Programming 1 Universality of Consensus Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit."

Similar presentations


Ads by Google