How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

24
How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language

description

void Toggle () { if (x == 0) x = 1; else x = 0; } Fetch value of x Store it in a temporary Compare with zero Based on the result, write new value What if, in the meanwhile, the original x was modified by another thread? Write is based on incorrect assumption!

Transcript of How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

Page 1: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

How D can make concurrent programming a piece of cake

Bartosz MilewskiD Programming Language

Page 2: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

• Multi-Core is here to stay• Programmers must use concurrency• (Dead-) Lock Oriented Programming

is BAD• New paradigm badly needed

Page 3: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

void Toggle (){ if (x == 0) x = 1; else x = 0;}

• Fetch value of x• Store it in a temporary• Compare with zero• Based on the result, write new value

What if, in the meanwhile, the original x was modified by another thread? Write is based on incorrect assumption!

Page 4: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

• Theorem:–Hypothesis: x == 0 (read x, compare to 0)– Conclusion: x = 1 (write 1 into x)

• Problem: Hypothesis invalidated before conclusion reached

• Must re-check the hypothesis before writing!

Page 5: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

• Delay checking: Log read values for later

• Must re-check before writing: Log the “intent to write” (speculative writes) for later execution

• Verify hypothesis : Are read values unchanged?

• Reach conclusion: Execute writes from log to memory

Page 6: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

• Concurrency issues postponed to the commit phase (read-check and write)

• Commit uses generic code, which can be optimized and tested once for all

• User code simple, less error-prone—code as if there were a single global lock

• Increased concurrency—executes as if every word were separately locked

• No deadlocks!

Page 7: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

• Start a transaction: create log• Speculative execution—reads and

writes logged• Commit phase (atomic)– Read-check–Write to memory

• If failure, restart transaction

Page 8: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

• Combining atomic operations using locks—almost impossible!

• Atomic (transacted) withdrawalatomic { acc.Withdraw (sum); }

• Atomic deposit—similar• Atomic transfer

atomic { accOne.Withdraw (sum); accTwo.Deposit (sum);}

Page 9: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

• Example: Producer/Consumeratomic{ Item * item = pcQueue.Get ();}

Item * Get () atomic // PCQueue method{ if (_queue.Count () == 0) retry; else return _queue.pop_front ();}

Page 10: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

• Restart transaction without destroying the log

• Make the read-log globally available• Block until any of the logged read

locations changes• Every commit checks the read-sets of

blocked transactions and unblocks the ones that overlap with its write-set

Page 11: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

• Consumer doesn’t have to specify what it’s waiting for

• Producer doesn’t have to signal anybody• Composability: Wait for two items

atomic{ item1 = pcQueue.Get (); item2 = pcQueue.Get ();}

Page 12: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

• Transactable (atomic) objects– Visible as opaque handles– Can be opened only inside transaction– Open (for read) returns a const pointer

to the actual object– Open for write clones the object and

returns pointer to the cloneatomic struct Foo { int x; }atomic Foo f (new Foo); // an opaque handleatomic { // start transaction Foo * foo = f.open_write (); ++foo.x;}

Page 13: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

• Deep copy of the object• Embedded atomic handles are copied

but not the objects they refer to• Transactable data structures build

from small atomic objects (tree from nodes)

• Value-semantic objects (e.g. structs) cloned by copy construction

Page 14: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

• Struct or class marked as “atomic”—all methods (except constructor) “atomic”

• Open and open_write can be called only inside a transaction—i.e. from inside: – Atomic block– Atomic function/method

• Atomic function/method may only be called from inside a transaction

Page 15: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

struct Slist // not atomic{

this () {// Insert sentinelsSNode * last = new SNode (Infin, null);_head = new SNode (MinusInfin, last);

}// atomic methodsconst (SNode) * Head () const atomic{

retrun _head.open ();}void Insert (int i) atomic;void Remove (int i) atomic;

private:atomic SNode _head; // atomic handle

}

Page 16: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

struct SNode atomic{public:

this (int i, const (SNode) * next) {_val = i; _next = next;

}// atomic methods (by default)int Value () const { return _val; }const (SNode) * Next () const {

return _next.open ();}Snode * SetNext (const (SNode) * next) {

SNode * self = this.open_write ()self._next = next;return self;

}private:

int _val;atomic Snode _next;

}

Page 17: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

atomic { myList.Insert (x); } // transactioned

void Insert (int i) atomic{

const (SNode) * prev = Head (); // sentinelconst (SNode) * cur = prev.Next ();while (cur._val < i){

prev = cur;cur = prev.Next ();

}assert (cur != 0); // at worst high sentinelSNode * newNode = new SNode (i, cur);(void) prev.SetNext (newNode);

}

Page 18: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

• Versioning and Locking– Global Version Clock (always even)– Version numbers always increase– (Hidden) version/lock word per atomic

object (lock is the lowest bit)• Consistent Snapshot maintenance– Version checks when opening an object– Read-check during commit

Page 19: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

• Transaction starts by reading Version Clock into the transaction’s read-version variable

• Open object– Check the object lock (bit). If taken,

abort– Check object version number. If it’s

greater than read-version abort

Page 20: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

• Every open is recorded in read-log– Pointer to original object (from which its

version lock can be retrieved)• Every open_write is recorded in read-

log and write_log– Pointer to original object– Pointer to clone

• Okay to call open_write after open (read)

Page 21: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

• Lock all objects recorded in the write-log– Bounded spinlock on each version lock

• Increment global Version Clock—store as transaction’s write-version

• Sequence Point (if transaction commits, that’s when it “happened”)

• Read-check– Re-check object version numbers against

read-version

Page 22: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

• For each location in the write-log– Swap the clone in place of original– Stamp it with write-version–Unlock

Page 23: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

• We have C implementation (Brad Roberts’ port of GPL’d Dice, Shalev, and Shalit)

• Write D implementation• Modify type system

Page 24: How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language.

• Dave Dice, Ori Shalev, and Nir Shavit. Transactional Locking II

• Tim Harris, Simon Marlow, Simon Peyton Jones, and Maurice Herlihy. Composable Memory Transactions. ACM Conference on Principles and Practice of Parallel Programming 2005 (PPoPP'05). 2005.