Transcript slides

Concurrent Revisions:
A deterministic concurrency model.
Daan Leijen & Sebastian Burckhardt
Microsoft Research
(OOPSLA 2010, ESOP 2011)
Consider Common Application Scenario:
Shared Data and Parallel Tasks
• Example 1: Office application
• Shared Data = Document
• Tasks = { Editing, Spellcheck,
Background Save, Paginate, …}
Reader
Mutator
R R R R
Reader
• Example 2: Game
• Shared Data = Game Objects
• Tasks = {Physics, Collision
Detection, AI, Render, Network}
 How to parallelize tasks?
(note: tasks do conflict
frequently)
Shared Data
Reader
Mutator
Mutator
Conventional Concurrency Control
• pessimistic concurrency control
use locks to avoid parallelism where
there are (real or potential) conflicts
• optimistic concurrency control
speculate on absence of true conflicts
rollback if there are real conflicts
either way: true conflicts kill parallel
performance.
Can we do better?
Our solution: Concurrent Revisions
Revision
Isolation Type
A Parallel Task that
gets its own logical
copy of the state
A type which supports
automatic replication and
conflict resolution
• Reminiscent of source control systems
• Conceptually, each revision gets its own
private copy of all the shared data
• On join, all effects of the joined revision are applied to
the joining revision
Revision vs. Traditional Isolation
Tasktypes:
declares shared data
Traditional Task
int x = 0;
task t = fork {
x = 1;
}
assert(x==0 || x==1);
join t;
assert(x==1);
Concurrent Revisions
versioned<int> x = 0;
revision r = rfork {
x = 1;
}
assert(x==0);
fork revision:
join r;
forks off a private copy of
assert(x==1);
the shared state
• Isolation: side effects are only visible when the
join revision:
revision is joined.
waits for the revision to
terminate and writes back
• Deterministic execution!
changes into the main revision
Sequential int x = 0;
Consistency int y = 0;
task t = fork {
if (x==0) y++;
}
if (y==0) x++;
join t;
Transactional
Memory
assert(
(x==0 && y==1)
|| (x==1 && y==0)
|| (x==1 && y==1));
Concurrent
Revisions
int x = 0;
int y = 0;
task t = fork {
atomic { if (x==0) y++; }
}
atomic { if (y==0) x++; }
join t;
versioned<int> x = 0;
versioned<int> y = 0;
revision r = rfork {
if (x==0) y++;
}
if (y==0) x++;
join r;
assert(
(x==0 && y==1)
|| (x==1 && y==0));
assert(x==1 && y==1);
The Simplest Isolation Type
Versioned<int> x;
x = 0
x = 1
On a write-write conflict, the
modification in the child revision
wins.
x = 0
x = 2
assert(x==2)
x = 1
x = 0
x = 0
assert(x==0)
x = 1
assert(x==1)
An Isolation Type with
Custom conflict resolution
Cumulative<int, merge> x;
int merge (
int current,
int join,
int original)
{
return current +
(join – original);
}
x = 0
0
x += 1
x += 2
1
merge(1,2,0)
→ 3
2
assert(x==3)
Revision Diagrams
• Describe the (dynamic) computation
 Information flows only along paths in diagram
• Not the same as previously known diagrams
for concurrency
 More general
than SP graphs
 Less general
than DAGs
 We proved: are
semi-lattices
… but a DAG
… but not an SP-graph
Case Study: Spacewars!
Sequential Game Loop
How to parallelize
given conflicts on
object positions?
Updates all positions
Writes some positions
Writes some positions
Reads all positions
Reads all positions
autosave
(long running)
network
Physics
Render
Coll. Det. 4
Coll. Det. 3
Coll. Det. 2
Coll. Det. 1
Revision Diagram for Parallelized Game Loop
autosave
(long running)
network
Physics
Render
Coll. Det. 4
Coll. Det. 3
Coll. Det. 2
 Render task reads
position of all game
objects
 Physics task updates
position of all game
objects
 No interference:
render task sees
consistent snapshot!
Coll. Det. 1
Example 1: read-write conflict.
autosave
(long running)
network
Physics
Render
Coll. Det. 4
Coll. Det. 3
Coll. Det. 2
 Physics task updates
position of all game
objects
 Network task updates
position of some
objects
 Network updates have
priority over physics
updates
 Order of joins
establishes correct
precedence!
Coll. Det. 1
Example 2: write-write conflict.
Results
Physics task
Render
Collision detection
 Autosave now perfectly unnoticeable in background
 Overall Speed-Up: 3.03x on four-core
(almost completely limited by graphics card)
Only a 5% slowdown in
the sequential case
Overhead:
Some individual tasks
How much does all the copying and the
indirection
cost?
slow
down much
more
(i.e. physics simulation)
Implementation
• For each versioned object, maintain multiple
copies
 Map revision ids to versions
 synchronization free access
to local copy (on x86)
Revision
Value
1
0
40
2
45
7
• New copies are allocated lazily
 Don’t copy on fork… copy on first write after fork
• Old copies are released on join
 No space leak
Full algorithm in the paper…
Semantics of Concurrent Revisions
[ESOP’11]
• Calculus (similar to AME-calculus by Abadi et al.)
 Untyped lambda-calculus with
mutable references and fork/join primitives
• Determinacy Proof
• Merge functions
 Discussion of ADTs and merge functions
 Relate to snapshot isolation (- nesting, - resolution)
• Revision Diagrams
 Prove: semilattice structure
Local operations
Synchronization
By construction, there is no
‘global’ state: just local state for
each revision
State is simply a (partial)
function from a location to a
value
Operational Semantics
s →r s’
means: revision r takes a step, transforming s to s’
Interested?
http://research.microsoft.com/revisions
Videos
• Channel 9 interview w/ Erik Meijer
Papers
• OOPSLA ‘10 on implementation and game
• ESOP ‘11 on semantics
The implementation
• Try it online at www.rise4fun.com
• Download binary release in near future
The end.
BACKUP SLIDES
Revisions are not Transactions
• Determinism
– Resolves conflicts deterministically.
– No failure: never rolls back
– Organized in a revision diagram
• No restrictions on revisions
– can be long-running
– can do I/O
• Conflicts don’t kill parallel performance
– Conflicts do not force serialization