software transactional memory l.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Software Transactional Memory PowerPoint Presentation
Download Presentation
Software Transactional Memory

Loading in 2 Seconds...

play fullscreen
1 / 24

Software Transactional Memory - PowerPoint PPT Presentation


  • 341 Views
  • Uploaded on

Software Transactional Memory. How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language. Obvious Things. Multi-Core is here to stay Programmers must use concurrency (Dead-) Lock Oriented Programming is BAD New paradigm badly needed. The Problem.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Software Transactional Memory' - victoria


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
software transactional memory

Software Transactional Memory

How D can make concurrent programming a piece of cake

Bartosz Milewski

D Programming Language

obvious things
Obvious Things
  • Multi-Core is here to stay
  • Programmers must use concurrency
  • (Dead-) Lock Oriented Programming is BAD
  • New paradigm badly needed
the problem
The Problem

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!

logically speaking
Logically Speaking
  • 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!
transaction
Transaction
  • 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
what does it buy us
What Does It Buy Us?
  • 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!
stm in a nutshell
STM in a Nutshell
  • Start a transaction: create log
  • Speculative execution—reads and writes logged
  • Commit phase (atomic)
    • Read-check
    • Write to memory
  • If failure, restart transaction
composability
Composability
  • Combining atomic operations using locks—almost impossible!
  • Atomic (transacted) withdrawalatomic { acc.Withdraw (sum); }
  • Atomic deposit—similar
  • Atomic transferatomic {accOne.Withdraw (sum);accTwo.Deposit (sum);}
blocking transactions
Blocking Transactions
  • Example: Producer/Consumer

atomic

{

Item * item = pcQueue.Get ();

}

Item * Get () atomic // PCQueue method

{

if (_queue.Count () == 0)

retry;

else

return _queue.pop_front ();

}

retry
Retry
  • 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
the beauty of retry
The Beauty of Retry
  • 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 ();

}

object based stm
Object-Based STM
  • 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 clone

atomic struct Foo { int x; }

atomic Foo f (new Foo); // an opaque handle

atomic { // start transaction

Foo * foo = f.open_write ();

++foo.x;

}

cloning
Cloning
  • 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
type system support
Type System Support
  • 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
singly linked list
Singly-Linked List

struct Slist // not atomic

{

this () {

// Insert sentinels

SNode * last = new SNode (Infin, null);

_head = new SNode (MinusInfin, last);

}

// atomic methods

const (SNode) * Head () const atomic

{

retrun _head.open ();

}

void Insert (int i) atomic;

void Remove (int i) atomic;

private:

atomic SNode _head; // atomic handle

}

slide16
Node

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;

}

insert
Insert

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

void Insert (int i) atomic

{

const (SNode) * prev = Head (); // sentinel

const (SNode) * cur = prev.Next ();

while (cur._val < i)

{

prev = cur;

cur = prev.Next ();

}

assert (cur != 0); // at worst high sentinel

SNode * newNode = new SNode (i, cur);

(void) prev.SetNext (newNode);

}

implementation
Implementation
  • 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
consistent snapshot
Consistent Snapshot
  • 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
logging
Logging
  • 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)
commit
Commit
  • 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
commit writes
Commit Writes
  • For each location in the write-log
    • Swap the clone in place of original
    • Stamp it with write-version
    • Unlock
d work
D Work
  • We have C implementation (Brad Roberts’ port of GPL’d Dice, Shalev, and Shalit)
  • Write D implementation
  • Modify type system
bibliography
Bibliography
  • 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.