Obstruction-free synchronization Article by: Maurice Herlihy, Victor Luchangco, Mark Moir Double-Ended Queues as an example Presentation : Or Peri.

Slides:



Advertisements
Similar presentations
Wait-Free Queues with Multiple Enqueuers and Dequeuers
Advertisements

CS492B Analysis of Concurrent Programs Lock Basics Jaehyuk Huh Computer Science, KAIST.
CS252: Systems Programming Ninghui Li Program Interview Questions.
Mutual Exclusion By Shiran Mizrahi. Critical Section class Counter { private int value = 1; //counter starts at one public Counter(int c) { //constructor.
Maged M. Michael, “Hazard Pointers: Safe Memory Reclamation for Lock- Free Objects” Presentation Robert T. Bauer.
Scalable and Lock-Free Concurrent Dictionaries
Stacks, Queues, and Deques. 2 A stack is a last in, first out (LIFO) data structure Items are removed from a stack in the reverse order from the way they.
Elementary Data Structures CS 110: Data Structures and Algorithms First Semester,
1 Queues (5.2) CSE 2011 Winter May Announcements York Programming Contest Link also available from.
Today’s Agenda  Stacks  Queues  Priority Queues CS2336: Computer Science II.
Scalable Synchronous Queues By William N. Scherer III, Doug Lea, and Michael L. Scott Presented by Ran Isenberg.
Parallel Processing (CS526) Spring 2012(Week 6).  A parallel algorithm is a group of partitioned tasks that work with each other to solve a large problem.
Locality-Conscious Lock-Free Linked Lists Anastasia Braginsky & Erez Petrank 1.
1 CMSC421: Principles of Operating Systems Nilanjan Banerjee Principles of Operating Systems Acknowledgments: Some of the slides are adapted from Prof.
Progress Guarantee for Parallel Programs via Bounded Lock-Freedom Erez Petrank – Technion Madanlal Musuvathi- Microsoft Bjarne Steensgaard - Microsoft.
1 Lecture 21: Transactional Memory Topics: consistency model recap, introduction to transactional memory.
Introduction to Lock-free Data-structures and algorithms Micah J Best May 14/09.
1 Lecture 23: Transactional Memory Topics: consistency model recap, introduction to transactional memory.
Computer Laboratory Practical non-blocking data structures Tim Harris Computer Laboratory.
CS510 Advanced OS Seminar Class 10 A Methodology for Implementing Highly Concurrent Data Objects by Maurice Herlihy.
CS 206 Introduction to Computer Science II 10 / 15 / 2008 Instructor: Michael Eckmann.
CS533 - Concepts of Operating Systems 1 Class Discussion.
Circular queue. Array-based Queue Use an array of size N in a circular fashion Three variables keep track of the front, rear, and size f index of the.
Recursion Chapter 7. Chapter 7: Recursion2 Chapter Objectives To understand how to think recursively To learn how to trace a recursive method To learn.
CHAPTER 10 Recursion. 2 Recursive Thinking Recursion is a programming technique in which a method can call itself to solve a problem A recursive definition.
Stacks, Queues, and Deques
SUPPORTING LOCK-FREE COMPOSITION OF CONCURRENT DATA OBJECTS Daniel Cederman and Philippas Tsigas.
Stack and Queue.
CHAPTER 05 Compiled by: Dr. Mohammad Omar Alhawarat Stacks & Queues.
Parallel Programming Philippas Tsigas Chalmers University of Technology Computer Science and Engineering Department © Philippas Tsigas.
ISOM MIS 215 Module 3 – Stacks and Queues. ISOM Where are we? 2 Intro to Java, Course Java lang. basics Arrays Introduction NewbieProgrammersDevelopersProfessionalsDesigners.
Simple Wait-Free Snapshots for Real-Time Systems with Sporadic Tasks Håkan Sundell Philippas Tsigas.
Nachos Phase 1 Code -Hints and Comments
Software Transactional Memory for Dynamic-Sized Data Structures Maurice Herlihy, Victor Luchangco, Mark Moir, William Scherer Presented by: Gokul Soundararajan.
Copyright 2007 Sun Microsystems, Inc SNZI: Scalable Non-Zero Indicator Yossi Lev (Brown University & Sun Microsystems Laboratories) Joint work with: Faith.
Recursion Chapter 7. Chapter Objectives  To understand how to think recursively  To learn how to trace a recursive method  To learn how to write recursive.
Håkan Sundell, Chalmers University of Technology 1 NOBLE: A Non-Blocking Inter-Process Communication Library Håkan Sundell Philippas.
November 15, 2007 A Java Implementation of a Lock- Free Concurrent Priority Queue Bart Verzijlenberg.
Copyright 2003 Scott/Jones Publishing Standard Version of Starting Out with C++, 4th Edition Chapter 18 Stacks and Queues.
Optimistic Design 1. Guarded Methods Do something based on the fact that one or more objects have particular states  Make a set of purchases assuming.
Maged M.Michael Michael L.Scott Department of Computer Science Univeristy of Rochester Presented by: Jun Miao.
1 Contention Management and Obstruction-free Algorithms Niloufar Shafiei.
Stacks And Queues Chapter 18.
Intro  Scratchpad rings and queues.  First – In – Firs – Out (FIFO) data structure.  Rings are fixed-sized, circular FIFO.  Queues not fixed-size.
A Methodology for Creating Fast Wait-Free Data Structures Alex Koganand Erez Petrank Computer Science Technion, Israel.
COSC 2007 Data Structures II Chapter 13 Advanced Implementation of Tables IV.
Practical concurrent algorithms Mihai Letia Concurrent Algorithms 2012 Distributed Programming Laboratory Slides by Aleksandar Dragojevic.
CS510 Concurrent Systems Why the Grass May Not Be Greener on the Other Side: A Comparison of Locking and Transactional Memory.
Hazard Pointers: Safe Memory Reclamation for Lock-Free Objects Maged M. Michael Presented by Abdulai Sei.
Gal Milman Based on Chapter 10 (Concurrent Queues and the ABA Problem) in The Art of Multiprocessor Programming by Herlihy and Shavit Seminar 2 (236802)
M1G Introduction to Programming 2 3. Creating Classes: Room and Item.
Priority Queues Dan Dvorin Based on ‘The Art of Multiprocessor Programming’, by Herlihy & Shavit, chapter 15.
2005MEE Software Engineering Lecture 7 –Stacks, Queues.
MULTIVIE W Slide 1 (of 21) Software Transactional Memory Should Not Be Obstruction Free Paper: Robert Ennals Presenter: Emerson Murphy-Hill.
Data Structures David Kauchak cs302 Spring Data Structures What is a data structure? Way of storing data that facilitates particular operations.
Hazard Pointers: Safe Memory Reclamation for Lock-Free Objects MAGED M. MICHAEL PRESENTED BY NURIT MOSCOVICI ADVANCED TOPICS IN CONCURRENT PROGRAMMING,
Scalable lock-free Stack Algorithm Wael Yehia York University February 8, 2010.
Lecture 10 b Stacks b Queues. 2 Stacks b A stack ADT is linear b Items are added and removed from only one end of a stack b It is therefore LIFO: Last-In,
Semaphores Chapter 6. Semaphores are a simple, but successful and widely used, construct.
Given a node v of a doubly linked list, we can easily insert a new node z immediately after v. Specifically, let w the be node following v. We execute.
CS6045: Advanced Algorithms Data Structures. Dynamic Sets Next few lectures will focus on data structures rather than straight algorithms In particular,
Lecture 20: Consistency Models, TM
Understanding Algorithms and Data Structures
Lecture 25 More Synchronized Data and Producer/Consumer Relationship
Lecture 6: Transactions
Lecture 22: Consistency Models, TM
Cs212: Data Structures Computer Science Department Lecture 7: Queues.
CS6045: Advanced Algorithms
Lecture: Consistency Models, TM
LINEAR DATA STRUCTURES
Presentation transcript:

Obstruction-free synchronization Article by: Maurice Herlihy, Victor Luchangco, Mark Moir Double-Ended Queues as an example Presentation : Or Peri

Today’s Agenda Two obstruction-free, CAS-based implementations of Double-ended queues. o Linear array o Circular array

Why Obstruction-Free? Avoid locks. Non-blocking data sharing between threads. Greater flexibility in design compared with Lock- freedom and wait-freedom implementations. In practice, should provide the benefits of wait-free and lock-free programming.

What’s wrong with Locks? Deadlocks Low liveness Fault-handling Scalability

Defenitions (a reminder) A synchronization technique is wait-free if it ensures that every thread will continue to progress in the face of arbitrary delay (or failure) of other threads. It is lock-free if it ensures that some thread always makes progress. It is Obstruction-free if it guarantees progress for any thread that eventually executes in isolation.

Obstruction-freedom ensures No thread can be blocked by delays or failures of other threads. Obstruction-free algorithms are simpler, and can be applied to complex structures. It does not guarantee progress when two (or more) conflicting threads execute concurrently. To improve progress one might add a contention reducing mechanism (“back-off reflex”). Pros & cons

lock-free and wait-free implementations use such mechanisms, but in a way that imposes a large overhead, even without contention. In scenarios with low contention, programming an Obstruction-free algorithm with some contention- manager, there’s the benefit from the simple and efficient design. Pros & cons

Double-ended queue- generalize FIFO queues and LIFO stacks. DEqueues Allows push\pop operations in both ends.

Remember “Job Stealing”? One application of DEqueues is as processors’ jobs queues. Each processor pops tasks from it’s own Dequeue’s head. DEqueues- what for? Job

Upon fork(), it pushes tasks to it’s DEqueue‘s head. If a processor’s queue is empty, it can “steal” tasks from another processor’s DEqueue‘s tail. DEqueues- what for? Job

First we’ll see the simpler, linear, array-based DEqueue. Second stage will extend the first one to “wrap around” itself. Implementation

Two special “null” values: LN and RN Array A[0,…,MAX+1] holds state. MAX is the queue’s maximal capacity. INVARIANT: the state will hold: LN + values * RN + An Oracle() function: o Parameter: left/right o Returns: an array index When Oracle(right) is invoked, the returned index is the leftmost RN value in A. Implementation – Intro

Each element i in A has: o A value: i.val o A version counter: i.ctr Version numbers are updated at every CAS operation. Linearization point: point of changing a value in A. Implementation – Intro

The Idea: o rightpush(v) will change the leftmost RN to v. o rightpop() will change the rightmost data to RN (and return it) o rightpush(v) returns “full” if there’s a non-RN value at A[MAX] o rightpop() returns “empty” if there are neighboring RN,LN Right/left push/pop are symmetric, so we only show one side. Implementation – Intro

1)Rightpush(v){ 2) While(true){ 3) k := oracle(right); 4) prev := A[k-1]; 5) cur := A[k]; 6) if(prev.val != RN and cur.val = RN){ 7) if(k = MAX+1) return “full”; 8) if( CAS(&A[k-1], prev, ) ) 9) if( CAS(&A[k], cur, ) ) 10) return “ok”; 11) } //end “if” 12) } //end “while” 13) } //end func Implementation – right push

1)Rightpop(){ 2) While(true){ 3) k := oracle(right); 4) cur := A[k-1]; 5) next := A[k]; 6) if(cur.val != RN and next.val = RN){ 7) if(cur.val = LN and A[k-1] = cur) 8) return “empty”; 9) if( CAS(&A[k], next, ) ) 10) if( CAS(&A[k-1], cur, ) ) 11) return cur.val; 12) } //end “if” 13) } //end “while” 14) } //end func Implementation – right pop

Relies on three claims: o In a rightpush(v) operation, at the moment we “CAS“ A[k].val from an RN value to v, A[k-1].val is not RN. o In a rightpop() operation, at the moment we “CAS” A[k-1].val from some v to RN, A[k].val contains RN. o If rightpop() returns “empty”, then at the moment it performed next:=A[k] (and just after: cur:=A[k-1]), these two values were LN and RN. Linearizability

The third claim: o If rightpop() returns “empty”, then at the moment it performed next:=A[k] (and just after: cur:=A[k-1]), these two values were LN and RN. holds since: 4)cur := A[k-1]; 5)next := A[k]; 6) if(cur.val != RN and next.val = RN){ 7) if(cur.val = LN and A[k-1] = cur) 8) return “empty”; A[k-1] didn’t change version number from line 4 to 7 so did A[k] from line 5 to 6. Linearizability

The first two claims hold similarly: o Since CAS operations check version numbers, only if no one interfered with another push/pop, we can perform the operation o In rightpush(v) for example: 4)prev := A[k-1]; 5)cur := A[k]; 6)if(prev.val != RN and cur.val = RN){ 7) if(k = MAX+1) return “full”; 8) if( CAS(&A[k-1], prev, ) ) 9) if( CAS(&A[k], cur, ) ) Counter didn’t change (upon success) from line 5 to 9, hence so did the value. Same holds for the neighbor (k-1) from line 4 to 8 Linearizability

Implementing the Oracle() function: o For linearizability, we only need oracle() to return an index at range. o For Obstruction-freedom we have to show that it is eventually accurate if invoked repeatedly without interference. Naïve approach is to simply go over the entire array and look for the first RN. Another approach is to keep “hints” (last position, for instance), and search around them. We can update these hints frequently or seldom with respect to cache locations… but that’s off-topic Linearizability

The Idea: o A[0] is “immediately to the right” of A[MAX+1]. o All indices are calculated modulo MAX+2. Two main differences: o To return “full” we must be sure there are exactly two null entries. o A rightpush operation may encounter a LN value  we’ll convert them into RN values (using another null character: DN). Extension to circular array

All null values are in a contiguous sequence in the array. This sequence is of the form: RN* DN* LN* There are at least 2 different types of null values in the sequence. Circular array - Invariants

We don’t invoke oracle(right) directly. Instead, we have rightCheckOracle() which returns: o K  an array index o Left  A[k-1]’s last content o Right  A[k]’s last content This guarantees: o right.val = RN o Left.val != RN Circular array - Implementation

rightCheckedOracle() 1)While(true){ 2) k := oracle(right); 3) left := A[k-1]; 4) right := A[k]; 5) if(right.val = RN and left.val != RN) 6) return k,left,right; 7) if( right.val = DN and !(left.val in {RN,DN}) ) 8) if( CAS(&A[k-1], left, ) ) 9) if( CAS(&A[k], right, ) ) 10) return k,, ; 11) } //end “while”

The array is not “full” when A[k+1] is RN. this is since A[k] is RN and an Invariant holds that “There are at least 2 different types of null values in the sequence”. So, if A[k+1] = LN  try converting it to DN If A[k+1] = DN  try converting it to RN In this case, we need to check “nextnext”. The major change – rightPush(v)

rightPush(v) 1)While(true){ 2) k,prev,cur := rightCheckedOracle(); 3) next := A[k+1]; 4) if( next.val = RN )//change RN to v 5) if( CAS(&A[k-1], prev, ) ) 6) if( CAS(&A[k], cur, ) ) 7) return “ok”; 8) if( next.val = LN ) //change LN to DN 9) if( CAS(&A[k], cur, ) ) 10) if( CAS(&A[k+1], next, ) ) 11) if(next.val = DN)

rightPush(v) 11) if(next.val = DN){ 12) nextnext:= A[k+2]; 13) if( !(nextnext.val in {RN,LN,DN}) ) 14) if(A[k-1] = prev) 15) if(A[k] = cur) 16) return “full”; 17) if( nextnext.val = LN) //DN to RN 18) if( CAS(&A[k+2], nextnext, ) ) 11) CAS(&A[k+1], next, ); 12) } //end “if” 13)}//end “while”

rightPop() 1)While(true){ 2) k,cur,next := rightCheckedOracle(); 3) if( cur.val in {LN,DN} and A[k-1] = cur ) 4) return “empty”; 5) if( CAS(&A[k], next, ) ) 6) if( CAS(&A[k-1], cur, ) ) 7) return cur.val; 8)}//end “while”

Is harder to prove in this case (there’s a whole other article just to do so). The main difficulty: proving that when rightPush(v) changes a value, it has an RN or an DN to it’s right. There are 5 lines in the code (of the right side functions) which may interrupt with this, but they are all using CAS, and intuitively, the.ctr values should assure correctness. Linearizability

We’ve seen Two Obstruction-free implementations of a Dequeue. As promised, they are pretty simple. Hopefully, I’ve managed to demonstrate the main degradation, as well as an intuition as to why it’s a good solution for relatively low contention scenarios To Sum up

Questions? ?