COS 226_05 - Acknowledgement COS 226 Chapter 5 The Relative...

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: Acknowledgement COS 226 Chapter 5 The Relative Power of Primitive Synchronization Operations Some of the slides are taken from the companion slides for “The Art of Multiprocessor Programming” by Maurice Herlihy & Nir Shavit Goal To identify a set of primitive synchronization operations powerful enough to solve synchronization problems likely to arise in practise To do this we need a way to evaluate the power of various synchronization operations What can they solve and how efficiently? Wait-Free Implementation Every method call completes in finite number of steps Implies no mutual exclusion From Weakest Register Single writer All the way to a Wait-free Implementation of Atomic Registers MRMW MRSW 1 Single reader M-valued Boolean 01 1 Safe Boolean register SRSW Safe Regular Atomic Rationale for wait-freedom We wanted atomic registers to implement mutual exclusion So we couldn’t use mutual exclusion to implement atomic registers But wait, there’s more! Why is Mutual Exclusion so wrong? Asynchronous Interrupts ??? ??? Sw app bac ed ou t ka t Heterogeneous Processors ??? ??? yawn Pentium Pentium 286 Fault-tolerance ??? ??? Basic Questions Wait-Free synchronization might be a good idea in principle But how do you do it Systematically? Correctly? Efficiently? FIFO Queue: Enqueue Method FIFO Queue: Dequeue Method q.enq( ) q.deq()/ q.deq()/ Two-Thread Wait-Free Queue public class LockFreeQueue { int head = 0, tail = 0; Item[QSIZE] Item[QSIZE] items; public void enq(Item x) { while (tail-head == QSIZE) {}; items[tail % QSIZE] = x; tail++; } deq() public Item deq() { while (tail-head == 0) {} Item item = items[head % QSIZE]; return head++; return item; }} What About Multiple Dequeuers? Grand Challenge Consensus While you are ruminating on the grand challenge… We will give you another puzzle Consensus Important … Implement a FIFO queue Wait-free Linearizable From atomic read-write registers Multiple dequeuers Only new aspect Consensus: Each Thread has a Private Input They Communicate 32 19 21 They Agree on One Thread’s Input Formally: Consensus A consensus object has a decide() method Each thread calls the decide() method with its input once decide() returns a value with the following conditions: Consistent: all threads decide the same value 19 19 19 Valid: the common decision value is some thread's input decide(32) public class FIFOqueue { … (int int decide (int value) { … decide(19) 19 public class FIFOqueue { … (int int decide (int value) { … 19 19 19 19 decide(21) 19 Consensus We are now going to look at different concurrent object classes and see whether they solve consensus Atomic Registers Can we solve consensus using atomic registers? Start with binary consensus for 2 threads No Wait-Free Implementation of Consensus using Registers ??? ??? Wait-Free Computation A moves B moves Either A or B “moves” Moving means Register read Register write The Two-Move Tree Final states Initial state Decision Values 1 0 0 1 1 1 Bivalent: Both Possible bivalent Univalent: Single Value Possible univalent 1 0 0 1 1 1 1 0 0 1 1 1 x-valent: x Only Possible Decision 1-valent 0-valent Summary Wait-free computation is a tree Bivalent system states Outcome not fixed Univalent states Outcome is fixed May not be “known” yet 1 0 0 1 1 1 1-Valent and 0-Valent states Back to Atomic Registers… Both Inputs 0 0 0 Univalent: all executions must decide 0 Both Inputs 0 0 Both Inputs 1 1 1 Including this solo execution by A Univalent: all executions must decide 1 Both Inputs 1 1 What if inputs differ? 0 1 Including this solo execution by B The Possible Executions 0 1 The Possible Executions 0 1 Include the solo execution by A that decides 0 Also include the solo execution by B which decides 1 Possible Executions Include The Proof Suppose there exists a binary consensus protocol for two threads A and B Suppose A’s next move changes the protocol to a 0-valent state Suppose B’s next move changes the protocol to a 1-valent state What methods could A and B be about to call? 0 1 Solo execution by A must decide 0 Solo execution by B must decide 1 Atomic Registers Method calls: One of the threads reads from the register Both threads write to separate registers, or Both threads write to the same registers Method call: One thread reads Suppose A is about to read from a register B is about to do… whatever Scenario 1 B moves first – 1valent B then runs solo and decides 1 Scenario 2 c B moves B runs solo 1 1-valent A moves first – 0A reads valent B then runs solo and decides 0 c B runs solo B moves B runs solo 0-valent tr on C 0 ion ct1 i ad 1-valent Method call: Both write to separate registers Suppose A is about to write to register r0 Suppose B is about to write to register r1 Scenario 1 A writes first to r0 B then writes to r1 A writes r0 c B writes r1 0 0-valent Scenario 2 B writes first to r1 A then writes to r0 A writes r0 B writes r1 Method call: Both write to same register c B writes r1 A writes ion ct r i ad 1 0 Suppose both threads A and B are about to write to the same register r tr on 0-valent C 0 1-valent Scenario 1 A writes first A writes B then runs solo and decides 0 Scenario 2 c B writes first A writes B then runs solo and decides 1 c B writes B writes B writes B runs solo 0 B nuns r tiosolo ic B runs d a1 tr solo on C0 Conclusion Atomic registers cannot do consensus. Theorem 5.2.1 Atomic registers have consensus number 1. Consensus numbers: The consensus number of a class is the largest number of threads that can solve consensus. Consensus number 1 means only sequential. Protocol states A protocol state is critical if: It is bivalent and If any thread moves, the protocol state becomes univalent. Lemma 5.1.3 Every wait-free consensus protocol has a critical state. What Does Consensus have to do with Concurrent Objects? Consensus Object Consensus public interface Consensus { Object decide(object value); } Generic Consensus Protocol ConsensusProtocol<T> abstract class ConsensusProtocol<T> implements Consensus { protected T proposed = new T[N]; protected void propose(T value) { proposed[ThreadID.get()] proposed[ThreadID.get()] = value; } abstract public T decide(T value); } Generic Consensus Protocol ConsensusProtocol<T> abstract class ConsensusProtocol<T> implements Consensus { new protected T proposed = new T[N]; protected void propose(T value) { proposed[ThreadID.get()] proposed[ThreadID.get()] = value; } abstract public T decide(T value); proposed value } Each thread’s Generic Consensus Protocol ConsensusProtocol<T> abstract class ConsensusProtocol<T> implements Consensus { protected T proposed = new T[N]; protected void propose(T value) { proposed[ThreadID.get()] proposed[ThreadID.get()] = value; } abstract public T decide(T value); Propose a value } Generic Consensus Protocol ConsensusProtocol<T> abstract class ConsensusProtocol<T> Decide a value: abstract method implements Consensus { means subclass does the new T[N]; heavy lifting protected T proposed = (real work) protected void propose(T value) { proposed[ThreadID.get()] proposed[ThreadID.get()] = value; } abstract public T decide(T value); } FIFO Queue Can a FIFO Queue Implement Consensus? Let’s start with 2-threads… FIFO Consensus Protocol: Write Value to Array 2-Threads attempt to enqueue a value at the same time proposed array FIFO Queue with red and black balls 0 0 1 8 Coveted red ball Dreaded black ball Protocol: Take Next Item from Queue Protocol: Take Next Item from Queue I got the 0 ball, coveted red 1 so I will decide my value I got the dreaded black ball, so I will decide the other’s value from the array 8 0 8 0 1 Consensus Using FIFO Queue public class QueueConsensus extends ConsensusProtocol { queue; private Queue queue; QueueConsensus() public QueueConsensus() { new queue = new Queue(); queue.enq(Ball.RED); queue.enq(Ball.RED); queue.enq(Ball.BLACK); queue.enq(Ball.BLACK); } … } Initialize Queue public class QueueConsensus extends ConsensusProtocol { queue; private Queue queue; QueueConsensus() public QueueConsensus() { this.queue = new Queue(); this.queue.enq(Ball.RED); this.queue.enq(Ball.RED); this.queue.enq(Ball.BLACK); this.queue.enq(Ball.BLACK); } … } 8 Who Won? public public class QueueConsensus extends ConsensusProtocol { queue; private Queue queue; … public decide(object value) { propose(value); propose(value); this.queue.deq(); Ball ball = this.queue.deq(); Ball.RED) if (ball == Ball.RED) proposed[i]; return proposed[i]; else proposed[1return proposed[1-i]; } } Who Won? public class QueueConsensus extends ConsensusProtocol { queue; private Queue queue; … public decide(object value) { propose(value); propose(value); this.queue.deq(); Ball ball = this.queue.deq(); Ball.RED) if (ball == Ball.RED) proposed[i]; return proposed[i]; else proposed[1return proposed[1-ij]; } Race to dequeue } first queue item Who Won? public class QueueConsensus extends ConsensusProtocol { queue; private Queue queue; … public decide(object value) { propose(value); propose(value); this.queue.deq(); Ball ball = this.queue.deq(); Ball.RED) if (ball == Ball.RED) proposed[i]; return proposed[i]; else proposed[1return proposed[1-i]; i = ThreadID.get(); } I win if I was } Who Won? public class QueueConsensus extends ConsensusProtocol { queue; private Queue queue; Other thread wins if … I was public decide(object value) { second propose(value); propose(value); this.queue.deq(); Ball ball = this.queue.deq(); Ball.RED) if (ball == Ball.RED) proposed[i]; return proposed[i]; else proposed[1return proposed[1-i]; } } first FIFO Queues Although FIFO queues solve two-thread consensus, they cannot solve 3-thread consensus. Why? Proof by contradiction Assumptions: we have a consensus protocol for threads A, B and C The protocol has a critical state s A’s next move will make the protocol 0-valent B’s next move will make the protocol 1-valent What methods would they be about to call? Proof A and B’s pending moves can only be to both call methods of the same object Thus they are about to call methods of a single queue object Possible method calls A and B both call deq() On thread calls enq() and another calls deq() A and B both call enq() Both call deq() – Scenario 1 A dequeues Then B dequeues Then C runs solo A deq Both call deq() – Scenario 2 B dequeues Then A dequeues Then C runs solo A deq c B deq c B deq B deq C runs solo C runs solo 0 tr on 1 0 C ion ct i aCdruns solo A deq One calls enq() and one calls deq() Suppose A calls enq(a) and B calls deq() If the queue is non-empty: C cannot observe the order in which they occurred since they operate on different ends of the queue Both call enq() A enq(a) c If the queue is empty: The 1-valent state (B deq() then A enq()) is indistinguishable from the 0-valent state if A enq()’s alone tr on C t dic a ion Scenario 1 B enq(b) A enq(a) A deq a B enq(b) Run A untils it deq() a Run B until is deq() b B deq b C runs solo C runs solo 0 Both call enq() A enq(a) c B enq(b) Theorem 5.4.1 FIFO queues have consensus number 2. Scenario 1 B enq(b) B enq(b) A deq a A enq(a) Run A untils it deq() b Run B until is deq() c B deq b C runs solo A enq(a) A deq b C runs solo tr on C 0 t dic a 1 B deq a C runs solo ion Read-modify-write operations Many synchronization operations can be described as read-modify-write (RMW) operations In object form: read-modify-write registers RMW Methods A method is an RMW for the function set F if it atomically replaces register value v with f(v) for some f E F and returns v RMW Methods From java.util.concurrent: getAndSet(x): Replaces current value with x and returns prior value fv(x) = v RMW Methods getAndAdd(k) Atomically adds k to the current value and returns the prior value fk(x) = x + k get() Returns the register’s value getAndIncrement() Atomically adds 1 to the current value and returns the old value fv(x) = v + 1 The Exception compareAndSet() Takes 2 values – expected value e and update value u If value is equal to e, it replaces it with u otherwise it remains unchanged Exception: it returns a Boolean value to indicate whether value was changed Read-Modify-Write public abstract class RMWRegister { private int value; public int synchronized getAndMumble() getAndMumble() { this.value; int prior = this.value; mumble(this.value); this.value = mumble(this.value); return prior; } } Read-Modify-Write public abstract class RMWRegister { private int value; public int synchronized getAndMumble() getAndMumble() { this.value; int prior = this.value; mumble(this.value); this.value = mumble(this.value); return prior; } Return prior value } Read-Modify-Write public abstract class RMWRegister { private int value; public int synchronized getAndMumble() getAndMumble() { this.value; int prior = this.value; mumble(this.value); this.value = mumble(this.value); return prior; } Apply function to current value } Example: getAndSet public abstract class RMWRegister { private int value; public int synchronized getAndSet(int v) { this.value; int prior = this.value; this.value = v; return prior; } … } Example: getAndSet (swap) public abstract class RMWRegister { private int value; public int synchronized getAndSet(int v) { this.value; int prior = this.value; this.value = v; return prior; } … F(x)=v is constant function } getAndIncrement public public abstract class RMWRegister { private int value; public int synchronized getAndIncrement() getAndIncrement() { this.value; int prior = this.value; this.value = this.value + 1; return prior; } … } getAndIncrement public abstract class RMWRegister { private int value; public int synchronized getAndIncrement() getAndIncrement() { this.value; int prior = this.value; this.value = this.value + 1; return prior; } … F(x) = x+1 } getAndAdd public abstract class RMWRegister { private int value; public int synchronized getAndAdd(int a) { this.value; int prior = this.value; this.value = this.value + a; return prior; } … } Example: getAndAdd public abstract class RMWRegister { private int value; public int synchronized getAndIncrement(int a) { this.value; int prior = this.value; this.value = this.value + a; return prior; } … F(x) = x+a } compareAndSet public abstract class RMWRegister { private int value; public boolean synchronized compareAndSet(int expected, int update) { this.value; int prior = this.value; (this.value this.value==expected) if (this.value==expected) { this.value = update; return true; } return false; }…} compareAndSet public abstract class RMWRegister { private int value; public boolean synchronized compareAndSet(int expected, int update) { this.value; int prior = this.value; (this.value this.value==expected) if (this.value==expected) { this.value = update; return true; } return false; If value is what was expected, … }…} compareAndSet public public abstract class RMWRegister { private int value; public boolean synchronized compareAndSet(int expected, int update) { this.value; int prior = this.value; (this.value this.value==expected) if (this.value==expected) { this.value = update; return true; } return false; … replace it }…} compareAndSet public abstract class RMWRegister { private int value; public boolean synchronized compareAndSet(int expected, int update) { this.value; int prior = this.value; (this.value this.value==expected) if (this.value==expected) { this.value = update; return true; } return false; Report success }…} compareAndSet public abstract class RMWRegister { private int value; public boolean synchronized compareAndSet(int expected, int update) { this.value; int prior = this.value; (this.value this.value==expected) if (this.value==expected) { this.value = update; return true; } Otherwise report failure return false; }…} Definition A RMW method W ith function mumble(x) is non-trivial if there exists a value v Such that v ≠ mumble(v) Par Example Identity(x) = x is trivial Theorem Any non-trivial RMW object has consensus number of 2 getAndIncrement(x) = x+1 is non-trivial Reminder Subclasses of consensus have consensus propose(x) propose(x propose(x) method which just stores x into proposed[i] proposed[i proposed[i] built-in method Proof public class RMWConsensus extends ConsensusProtocol { private RMWRegister r = v; public Object decide(object value) { propose(value); propose(value); (r.getAndMumble r.getAndMumble() if (r.getAndMumble() == v) proposed[i]; return proposed[i]; else proposed[j]; return proposed[j]; }} decide(object decide(object value) method which determines winning value customized, class-specific method Proof public class RMWConsensus extends ConsensusProtocol { private RMWRegister r = v; public Object decide(object value) { propose(value); propose(value); (r.getAndMumble r.getAndMumble() if (r.getAndMumble() == v) proposed[i]; return proposed[i]; Initialized to v else proposed[j]; return proposed[j]; }} Proof public class RMWConsensus extends Consensus { Am I first? private RMWRegister r = v; public Object decide(object value) { (r.getAndMumble r.getAndMumble() if (r.getAndMumble() == v) proposed[i]; return proposed[i]; else proposed[j]; return proposed[j]; }} Proof public class RMWConsensus extends ConsensusProtocol { private RMWRegister r = v; public Object decide(object value) { propose(value); propose(value); Yes, return my (r.getAndMumble r.getAndMumble() if (r.getAndMumble() == v)input proposed[i]; return proposed[i]; else proposed[j]; return proposed[j]; }} Proof public class RMWConsensus extends ConsensusProtocol { private RMWRegister r = v; public Object decide(object value) { propose(value); propose(value); (r.getAndMumble r.getAndMumble() if (r.getAndMumble() == v) proposed[i]; return proposed[i]; No, return other’s else input proposed[j]; return proposed[j]; }} Proof We have displayed A two-thread consensus protocol Using any non-trivial RMW object Common2 RMW Operations Let F be a set of functions such that for all fi and fj, either Commute: fi(fj(v))=fj(fi(v)) Overwrite: fi(fj(v))=fi(v) Claim: Any set of RMW objects that commutes or overwrites has consensus number exactly 2 Examples getAndSet() Overwrite Common2 RMW Registers Theorem: Any RMW register in Common2 has consensus number of 2. getAndAdd() Commute getAndIncrement() Commute Meanwhile Back at the Critical State A about to apply fA Proof by contradiction Suppose that a 3-thread protocol exists using only Common2 registers Possible method calls? c B about to apply fB 0-valent 1-valent Maybe the Functions Commute A applies fA Maybe the Functions Commute A applies fA c B applies fB c B applies fB These states look the same to C B applies fB A applies fA B applies fB A applies fA C runs solo C runs solo C runs solo 0-valent 0 1 1-valent 0-valent 0 d tr a 1n Co 1-valent C runs solo io ic t n Maybe the Functions Overwrite A applies fA Maybe the Functions Overwrite These states look the same to C A applies fA c B applies fB c B applies fB C runs solo A applies fA C runs solo 0 C runs solo 0-valent 0 1 1-valent 0-valent n io ct C runs solo di ra t 1n Co 1-valent A applies fA ...
View Full Document

This note was uploaded on 10/11/2010 for the course COS COS226 taught by Professor Klazar during the Spring '10 term at University of Pretoria.

Ask a homework question - tutors are online