LOCK/WAIT FREE SYNCHRONIZATION Synchronization Mutex Blocking - - PowerPoint PPT Presentation

lock wait free synchronization synchronization
SMART_READER_LITE
LIVE PREVIEW

LOCK/WAIT FREE SYNCHRONIZATION Synchronization Mutex Blocking - - PowerPoint PPT Presentation

LOCK/WAIT FREE SYNCHRONIZATION Synchronization Mutex Blocking Lock-free At least one operation in a set of concurrent operations finishes in a finite number of its processors own steps finishes in a finite number of its


slide-1
SLIDE 1

LOCK/WAIT FREE SYNCHRONIZATION

slide-2
SLIDE 2

Synchronization

  • Mutex

– Blocking

  • Lock-free

– At least one operation in a set of concurrent operations finishes in a finite number of its processor’s own steps finishes in a finite number of its processor’s own steps

  • Wait-free

– Every operation finishes in a finite number of its processor’s own steps

  • Lock-free and wait-free often require hardware

supported atomic operations

– Like compare-and-swap (CAS)

slide-3
SLIDE 3

CUDA Compare and Swap

int atomicCAS(int* address, int compare, int val);

  • Atomically:
  • ld = *address
  • old = *address

– Could be in global or shared memory – There is also a 64-bit version for global memory

  • new = (old == compare ? val : old)
  • *address = new
  • Return old
slide-4
SLIDE 4

Busy-Wait 2-Mutex?

shared int turn = 2; if(turn != !id) { // I can go in turn = id; turn = id; <<< critical section >> turn = 2; << non-critical section >> }

slide-5
SLIDE 5

Busy-Wait 2-Mutex?

  • Proposed by Hyman

shared boolean ready[2] = {0,0}; shared int turn = 0; while (true) { // Try to acquire lock ready[id] = 1; // Register my interest ready[id] = 1; // Register my interest while (turn != id) { // My turn? while (ready[!id] == 1) ; // Spin turn = id; } <<< critical section >> ready [id] = 0; << non-critical section >> }

slide-6
SLIDE 6

Busy-Wait 2-Mutex with CAS

shared int turn = 2; while(CAS(&turn, 2, id)); while(CAS(&turn, 2, id)); <<< critical section >> turn = 2; << non-critical section >>

slide-7
SLIDE 7

Example: Atomic Updates with CAS

class ClassName { Data *dptr; void Update() { Date *oldptr; Date *oldptr; Data *stage = new Data(“newvalue”); do {

  • ldptr = dptr;

} while (!CAS(&dptr, oldptr, stage)); } };

slide-8
SLIDE 8

Dynamic Load Balancing

  • Static Task list
  • While ( Next = WorkList.Front() != END )

– Perform work

  • Find a busy processor pb

– Share its load

Repeat

  • Repeat

– for a random processor pj – Nonblocking Lock LockList[pj]

  • Until lock not acquired
  • Share remaining load of processor pb = pj
  • [Edit Queue]
  • unlock LockList[pb]
slide-9
SLIDE 9

Non-blocking Lock

bool locked =

CAS(&LockList[victim], 0, threadID);

  • This is generally a busy-wait style
  • This is generally a busy-wait style
slide-10
SLIDE 10

Edit Queue

  • Delete the second half of unprocessed

WorkList[pb]

– In an array implementation: update end[pb]

  • Add it to WorkList[pi]

Add it to WorkList[pi]

  • Read new WorkList.Front[pb]

– Read front[pb]

  • Advance WorkList[pi] to new

WorkList.Front[pb]

– Start at new current[pb]

Race with pb’s update of its front: front++

slide-11
SLIDE 11

Load Stealing

Victim: ProcessMyShare: Oldfront = AtomicInc(&front); Thief: myEnd = End; End = (myEnd-front)/2 Myfront = front; if(Oldfront <= End)

WorkOn(oldFront);

Myfront = front; updateMyGlobals(); ProcessMyShare();

slide-12
SLIDE 12

Lock-free Linked List

  • Insertion: Switch in the new node atomically

Cursor0 Cursor1 n

slide-13
SLIDE 13

Lock-free Linked List

  • Insertion: Switch in the new node atomically

Cursor0 Cursor1

p s

But what if a concurrent delete(Cursor1) happened?

n->next = Cursor0->next CAS(&Cursor0->next, n->next, n)

n

slide-14
SLIDE 14

Deletion

PREV Cursor1 Cursor2

But what if, say, a concurrent insertAfter(Cursor2) happened? [Harris 01] uses markers to get past transient states

slide-15
SLIDE 15

Deletion [Harris 01]

PREV Cursor1

NEXT = Cursor1.next ; CAS (&Cursor1.next, NEXT, NEXT|MARK) And then: CAS(&(PREV.next), Cursor1, NEXT) Can something go wrong in between?

slide-16
SLIDE 16

Deletion [Harris 01]

do { update(&curr, &prev); Node *curr_next = curr.next; if (! marked_bit(curr_next)) // If marked, retry if (CAS(&curr.next, curr_next, mark(curr_next))) break; // Was able to mark } while (true); // Now fix list if (!CAS(&(prev.next), curr, curr_next)) Update(&curr, &prev); // also deletes marked nodes return true;

slide-17
SLIDE 17
slide-18
SLIDE 18

ABA problem

  • 18
slide-19
SLIDE 19

ABA Solutions

  • Double Compare&Swap
  • No Cell Reuse
  • No Cell Reuse
  • Memory Management
slide-20
SLIDE 20
  • q = new cell
  • Repeat

Insert ( p, x )

20

  • Repeat
  • r = SafeRead ( p -> next )
  • Write ( q -> next, r )
  • until Compare&Swap( p -> next, r, q )
slide-21
SLIDE 21
  • node * target;

// -> data node * pre_aux; // -> preceding auxiliary

struct Cursor {

21

  • node * pre_aux;

// -> preceding auxiliary node

  • node * pre_cell;

// -> previous cell

};

slide-22
SLIDE 22
  • // Updates pointers in the cursor so that it

becomes valid.

Update(cursor c) {

22

  • // removes double aux_node.

};

slide-23
SLIDE 23
  • c.pre_cell = next // deletes cell
  • back_link = c->pre_cell
  • delete pre_aux
  • Concurrent deletions may stall process and create

chains of aux nodes.

Try_delete(cursor c) {

23

chains of aux nodes.

  • The last deletion follows the back_links of the

deleted cells.

  • After all deletions the list will have no extra

aux_nodes

};