Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


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

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

2 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 2 Turing Computability A mathematical model of computation Computable = Computable on a T-Machine 011010 1

3 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 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© Copyright Herlihy-Shavit 2007 4 The Consensus Hierarchy 1 Read/Write Registers, Snapshots… 2 getAndSet, getAndIncrement, … ∞ compareAndSet,…...... FIFO Queue, LIFO Stack Multiple Assignment Can we implement them from any other object that has consensus number ∞? Like compareAndSet()…

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

6 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 6 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 …

7 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 7 Like a Turing Machine This construction –Illustrates what needs to be done –Optimization fodder Correctness, not efficiency –Why does it work? (Asks the scientist) –How does it work? (Asks the engineer) –Would you like fries with that? (Asks the liberal arts major)

8 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 8 A Generic Sequential Object public interface SeqObject { public abstract Response apply(Invocation invoc); }

9 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 9 A Generic Sequential Object public interface SeqObject { public abstract Response apply(Invocation invoc); } Push:5, Pop:null

10 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 10 Invocation public class Invoc { public String method; public Object[] args; }

11 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 11 Invocation public class Invoc { public String method; public Object[] args; } Method name

12 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 12 Invocation public class Invoc { public String method; public Object[] args; } Arguments

13 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 13 A Generic Sequential Object public interface SeqObject { public abstract Response apply(Invocation invoc); } OK, 4

14 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 14 Response public class Response { public Object value; } Return value

15 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 15 A Universal Concurrent Object public interface SeqObject { public abstract Response apply(Invocation invoc); } A universal concurrent object is a concurrent object that is linearizable to the generic sequential object

16 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 16 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

17 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 17 Lock-free Construction: Naïve Idea Use consensus object to store pointer to cell with current state Each thread creates new cell –computes outcome, –and tries to switch pointer to its outcome Unfortunately not… –consensus objects can be used once only

18 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 18 Naïve Idea enq deq

19 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 19 head Naïve Idea deq Concurrent Object enq ? Decide which to apply using consensus No good. Each thread can use consensus object only once

20 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 20 Why only once? Why is consensus object not readable? (1) 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 time 2-consensus. Not clear how to allow reuse of object or reading its state… Queue based consensus

21 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 21 Improved Idea: Linked-List Representation enq tail deq Each node contains a fresh consensus object used to decide on next operation

22 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 22 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 traversing the log upto the call

23 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 23 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

24 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 24 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

25 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 25 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

26 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 26 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

27 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 27 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)

28 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 28 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)

29 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 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 Seq number

30 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 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 Create a new node for a given method invocation

31 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 31 Universal Object head 123 decideNext (Consensus Object) Ptr to cell w/highest Seq Num Seq number, Invoc tail node next 4

32 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 32 Universal Object head 123 All threads repeatedly modify head…back to where we started? tail node 4

33 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 33 … 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

34 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 34 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 }

35 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 35 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

36 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 36 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

37 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 37 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

38 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 38 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

39 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 39 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

40 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 40 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

41 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 41 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

42 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 42 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 Return the node with max seq num

43 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 43 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; } …

44 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 44 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

45 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 45 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

46 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 46 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

47 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 47 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

48 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 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; } … Node at head of list that I will try to append to

49 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 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; } Decide winning node; could have already been decided

50 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 50 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 pointer based on decision Could have already been set by winner…in which case no affect

51 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 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; } … Set seq number indicating node was appended

52 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 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; } … add to head array so new head will be found

53 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 53 Part II – Compute Response nullenq( ) tail Red’s method call … deq() enq( ) Return Private copy of object

54 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 54 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); }

55 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 55 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 the result by sequentially applying the method calls in the list to a private copy of the object starting from the initial state

56 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 56 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 initialized copy of the sequential object

57 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 57 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); } First new method call is appended after the tail

58 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 58 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 not reached my own method call

59 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 59 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 the current nodes method to object

60 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 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); } Return the result after applying my own method call

61 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 61 Correctness List defines linearized sequential history Thread returns its response based on list order

62 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 62 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

63 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 63 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

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

65 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 65 … … Wait-free Construction head 123 tail i 4 announce Ptr to the cell thread i wants to append i

66 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 66 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

67 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 67 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

68 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 68 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

69 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 69 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

70 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 70 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 (node), asking help from others

71 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 71 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

72 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 72 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 some thread helping me)

73 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 73 Main Loop Non-zero sequence number indicates success Thread keeps helping append nodes Until its own node is appended

74 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 74 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

75 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 75 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

76 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 76 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

77 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 77 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 Who do I help?

78 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 78 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

79 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 79 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

80 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 80 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

81 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 81 Sliding Window Lemma After thread A announces its node No more than n other calls –Can start and finish –Without appending A’s node

82 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 82 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

83 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 83 The Sliding Help Window head 1 2 3 N+2 N+3 … announce 4 tail Help 3 Help 4 3

84 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 84 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

85 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 85 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!

86 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 86 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; }

87 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 87 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

88 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 88 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

89 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 89 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

90 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 90 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

91 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 91 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); }

92 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 92 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 the result after applying my own method call

93 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 93 Shared-Memory Computability Wait-free/Lock-free computable = Threads with methods that solve n- consensus 10011 Universal Object

94 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 94 public class RMWRegister { private int value; public boolean getAndSet(int update) { int prior = this.value; this.value = update; return prior; } GetAndSet is not Universal (1)

95 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 95 public class RMWRegister { private int value; public boolean getAndSet(int update) { int prior = this.value; this.value = update; return prior; } GetAndSet is not Universal (1) Consensus number 2

96 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 96 public class RMWRegister { private int value; public boolean getAndSet(int update) { int prior = this.value; this.value = update; return prior; } GetAndSet is not Universal (1) Not universal for ≥ 3 threads

97 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 97 public class RMWRegister { private int value; public boolean compareAndSet(int expected, int update) { int prior = this.value; if (this.value == expected) { this.value = update; return true; } return false; }} CompareAndSet is Universal (1)

98 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 98 public class RMWRegister { private int value; public boolean compareAndSet(int expected, int update) { int prior = this.value; if (this.value == expected) { this.value = update; return true; } return false; }} CompareAndSet is Universal (1) Consensus number ∞

99 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 99 public class RMWRegister { private int value; public boolean compareAndSet(int expected, int update) { int prior = this.value; if (this.value == expected) { this.value = update; return true; } return false; }} CompareAndSet is Universal (1) Universal for any number of threads

100 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 100 On Older Architectures IBM 360 –testAndSet (getAndSet) NYU UltraComputer –getAndAdd Neither universal –Except for 2 threads

101 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 101 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 …

102 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 102 Practical Implications Any architecture that does not provide a universal primitive has inherent limitations You cannot avoid locking for concurrent data structures … But why do we care?

103 Locking and Schedeuling What are the practical implications of locking? Locking affects the assumptions we need to make on the operating system in order to guarantee progress Lets understand how… Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 103

104 Schedeuling The scheduler is a part of the OS that determines –Which thread gets to run on which processor –How long it runs for A given thread can thus be active, that is, executing instructions, or suspended Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 104

105 Review Progress Conditions Deadlock-free: some thread trying to acquire the locks eventually succeeds. Starvation-free: every thread trying to acquire the locks eventually succeeds. Lock-free: some thread calling the method eventually returns. Wait-free: every thread calling the method eventually returns. Obstruction-free: every thread calling the method returns if it executes in isolation for long enough. 105

106 © 2007 Herlihy & Shavit 106 The Simple Snapshot is Obstruction-Free Put increasing labels on each entry Collect twice If both agree, –We’re done Otherwise, –Try again 1 22 1 7 13 18 12 = Collect2 Collect1 1 22 1 7 13 18 12

107 Obstruction-freedom In the simple snapshot alg: The update method is wait-free But the scan is obstruction-free: will complete only if it executes for long enough without concurrent updates. Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 107

108 Progress of Methods Some of the above defs refer to locks (part of implementation) or method calls And they ignore the scheduler Lets refine our progress definitions so that they apply to methods, and Take scheduling into account Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 108

109 A “Periodic Table” of Progress Conditions 109 Everyone makes progress Non-BlockingBlocking Someone makes progress Lock- free Starvation- free Deadlock- free Wait- free Obstruction- free

110 A bit more formally Standard notion of abstract object Progress conditions relate to method calls of an object Threads on a multiprocessor never fail: –A thread is active if it takes an infinite number of concrete (machine level) steps –And is suspended if not. 110

111 Maximal vs. Minimal For a given history H: Minimal progress: in every suffix of H, some method call eventually completes. Maximal progress: in every suffix of H, every method call eventually completes. 111

112 The “Periodic Table” of Progress Conditions 112 Maximal progress Non-BlockingBlocking Minimal progress Lock- free Starvation- free Deadlock- free Wait- free Obstruction- free

113 The Scheduler’s Role On a multiprocessor progress properties: Are not about the guarantees a method's implementation provides. They are about the scheduling assumptions needed in order to provide minimal or maximal progress. 113

114 Fair Scheduling A history is fair if each thread takes an infinite number of steps A method implementation is deadlock-free if it guarantees minimal progress in every fair history, and maximal progress in some fair history. 114

115 Starvation Freedom A method implementation is starvation-free if it guarantees maximal progress in every fair history. 115

116 Dependent Progress A progress condition is dependent if it does not guarantee minimal progress in every history, and is independent if it does. The blocking progress conditions (deadlock-freedom, Starvation- freedom) are dependent 116

117 Non-blocking Independent Conditions A method implementation is lock- free if it guarantees minimal progress in every history, and maximal progress in some history. A method implementation is wait- free if it guarantees maximal progress in every history. 117

118 The “Periodic Table” of Progress Conditions 118 Maximal progress Non-Blocking Blocking Minimal progress Lock- free Starvation- free Deadlock- free Wait- free Obstruction- free Independent Dependent

119 Uniformly Isolating Schedules A history is uniformly isolating if, for every k > 0, any thread that takes an infinite number of steps has an interval where it takes at least k contiguous steps Modern systems provide ways of providing isolation…later we will learn about “backoff” and “yeild”. 119

120 A Non-blocking Dependent Condition A method implementation is obstruction-free if it guarantees maximal progress in every uniformly isolating history. 120

121 The “Periodic Table” of Progress Conditions 121 Maximal progress Non-Blocking Blocking Minimal progress Lock- free Starvation- free Deadlock- free Wait- free Obstruction- free IndependentDependent Uniform iso scheduler Fair scheduler

122 The “Periodic Table” of Progress Conditions 122 Maximal progress Non-Blocking Blocking Minimal progress Lock- free Starvation- free Deadlock- free Wait- free Obstruction- free IndependentDependent ? Clash- free

123 Clash-Freedom: the “Einsteinium” of Progress A method implementation is clash-free if it guarantees minimal progress in every uniformly isolating history. Thm: clash-freedom strictly weaker than obstruction-freedom 123

124 Getting from Minimal to Maximal 124 Maximal progress Non-Blocking Blocking Minimal progress Lock- free Starvation- free Deadlock- free Wait- free Obstruction- free IndependentDependent ? Clash- free ? Helping But helping is expensive

125 Universal Constructions Our lock-free universal construction provides minimal progress A scheduler is benevolent for that algorithm if it guarantees maximal progress in every allowable history. Many real-world operating system schedulers are benevolent They do not single out any indiviudual thread 125

126 Getting from Minimal to Maximal 126 Maximal progress Non-Blocking Blocking Minimal progress Lock- free Starvation- free Deadlock- free Wait- free Obstruction- free IndependentDependent ? Clash- free ? Helping Universal Lock-free Construction Universal Wait-free Construction Use Wait-free/Lock-free Consensus Objects

127 Getting from Minimal to Maximal 127 Maximal progress Non-Blocking Blocking Minimal progress Lock- free Starvation- free Deadlock- free Wait- free Obstruction- free IndependentDependent ? Clash- free Universal Wait-free Construction Universal Lock-free Construction If we use Starvation-free/Deadlock-free Consensus Objects result is respectively Starvation-free/Deadlock-free

128 Benevolent Schedulers Consider an algorithm that guarantees minimal progress. A scheduler is benevolent for that algorithm if it guarantees maximal progress in every allowable history. Many real-world operating system schedulers are benevolent They do not single out any indiviudual thread 128

129 In Practice On a multiprocessor we will write code expecting maximal progress. Progress conditions will then define the scheduling assumptions needed in order to provide it. s129

130 This Means We will mostly write lock-free and lock-based deadlock-free algorithms… and expect them to behave as if they are wait-free… because modern schedulers can be made benevolent and fair. s130

131 Principles to Practice We learned how to define the safety (correctness) and liveness (progress) of concurrent programs and objects We are ready to start the practice of implementing them Next lecture: implementing spin locks on multiprocesor machines… Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 131

132 Art of Multiprocessor Programming© Copyright Herlihy-Shavit 2007 132 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.


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

Similar presentations


Ads by Google