slides

advertisement
Automatic Fine-Grain Locking
using
Shape Properties
Guy Golan Gueta
Nathan Bronson
Alex Aiken
G. Ramalingam
Mooly Sagiv
Eran Yahav
Tel-Aviv University
Stanford University
Stanford University
Microsoft Research
Tel-Aviv University
Technion
1
Concurrent Data Structures
• Widely used in many software systems
• Coarse-grain locking
– e.g.: a single lock
– easy to implement and understand
– often not efficient enough
• limited concurrency
• Fine-grain locking
– high-degree of concurrency
– extremely hard to implement and understand
2
Challenge:
Automatic Fine-Grain Locking
• Automatically add fine-grain locking to sequential code
– recursive data structures (e.g. trees, lists)
Sequential Code
Concurrent Code
int GetMax(Node p) {
Node c;
c = p.right;
while (c!=null) {
p=c;
c=c.right;
}
int t = p.value;
return t;
}
int GetMax(Node p) {
Node c; lock(p);
c = p.right; lock(c);
while (c!=null) { unlock(p);
p=c;
c=c.right; if(c!=null) lock(c);
}
int t = p.value; unlock(p);
return t;
}
3
Fine-Grain Locking
• Each heap object has its own lock
Data Structure
n1
n2
n4
n3
n5
n6
…
…
…
4
Fine-Grain Locking
• Each heap object has its own lock
• A lock is only held while necessary
Thread T’
Data Structure
n1
n2
Thread T
early unlock
n4
n3
n5
n6
…
…
…
5
Adding fine-grain locking is hard
• Adding fine-grain locking to pointer based
data structures is hard
• Need to understand complicated properties
• Hard in sequential programs
• Harder in the presence of concurrency
6
This paper provides two ideas
• Locking protocol for fine-grain locking, Domination Locking
–
–
–
–
Conditions that guarantees atomicity and deadlock-freedom
Can be enforced by programmers
Requires only sequential reasoning
Generalization of several known locking protocols
• Examples: hand-over-hand locking, dynamic DAG locking
• Automatic method to enforce the protocol
– Assumes that the heap is a forest at the beginning of each
operation
• Can be checked dynamically
– No use of shape analysis
– Static + Dynamic: adds conditional lock and unlock statements
7
Domination Locking Protocol
8
Restricted Objects Access
• Leverage the restricted way well-typed
programs access heap objects
– Cannot access n3 without accessing n2
Local Stack
Data Structure
n1
n2
X
n4
n3
n5
n6
…
…
…
9
Two Types of Objects
• Distinguishes between two types of objects:
– Exposed objects: “roots” of data structures
– Hidden objects: reachable only via exposed objects
exposed
Data Structure
n2
n3
…
hidden
Local Stack
n1
hidden
n5
…
X
n4
hidden
hidden
n6
…
hidden
10
Domination
Thread T dominates object u:
Paths from exposed objects to u include an
object locked by T
exposed
exposed
e1
e2
T dominates h4, h5
T does not dominate h3
Thread T
h3
h4
h5
11
Domination Locking Protocol
1. Thread can access object, only when holding its lock
exposed
e1
Thread T
h2
h3
12
Domination Locking Protocol
1. Thread can access object, only when holding its lock
2. Thread can lock hidden object u, only when it dominates u
Early unlock is legal
Cycle
exposed
e1
Thread T
h2
h3
13
Domination Locking Protocol
1. Thread can access object, only when holding its lock
2. Thread can lock hidden object u, only when it dominates u
Early unlock is legal
Cycle
exposed
e1
Thread T
h2
h3
h4
Heap graph can be dynamically changed14
Domination Locking Protocol
1. Thread can access object, only when holding its lock
2. Thread can lock hidden object u, only when it dominates u
3. For exposed objects, use variant of two-phase locking that
avoids deadlocks
Early unlock is legal
Cycle
exposed
e1
Thread T
h2
h3
h4
Heap graph can be dynamically changed15
Domination Locking Protocol
1. Thread can access object, only when holding its lock
2. Thread can lock hidden object u, only when it dominates u
3. For exposed objects, use variant of two-phase locking that
avoids deadlocks
Several exposed objects
exposed
e1
h2
h3
h4
exposed
e5
16
Concurrent Correctness from
Sequential Conditions
• If every sequential execution satisfies the protocol
and is able to terminate → all concurrent executions
are linearizable and are able to terminate
• Simplifies reasoning
• But automatic enforcement in real code with
complicated data structures is still not obvious
17
Sequential code
boolean remove(Nd par, int key) {
Nd n = null; n = par.right;
while (n != null && key != n.key) {
par = n;
n = (key < n.key) ? n.left : n.right;
}
if (n == null) return false;
Nd nL = n.left; Nd nR = n.right;
while (true) {
Nd bestChild = (nL == null ||
(nR != null && nR.prio > nL.prio)) ? nR : nL;
if (n == par.left)
par.left = bestChild;
else
par.right = bestChild;
if (bestChild == null) break;
if (bestChild == nL) { // ROTATION
n.left = nL.right; nL.right = n; nL = n.left;
} else {// ROTATION
n.right = nR.left; nR.left = n; nR = n.right;
}
par = bestChild;
}
return true;
}
?
18
Automatic Locking
for
Dynamic Forests
19
Dynamic Forest Data Structure
• In every sequential execution, shape is a forest
at the beginning and end of operations
• Example:
ListA
e1
h2
h3
h4
h6
h7
h8
ListB
e5
20
Dynamic Forest Data Structure
• In every sequential execution, shape is a forest
at the beginning and end of operations
• Example:
ListA
e1
Forest violation
h2
h3
Move h3 from ListA to ListB
ListB
e5
h4
h6
h7
h8
21
How does forestness help?
• Guarantees unique ownership at the
beginning of every operation
• Helps identifying where to safely release locks
22
Automatic Method
• Adds code that collects runtime information
• Adds code that uses this information for
locking and unlocking
23
Runtime Information
Two reference counters to every heap object
• Stack reference counter
– counts number of incoming pointers from local
stack (private memory)
• Heap reference counter
– counts number of incoming pointers from heap
objects
24
Runtime Information
h4
Local Stack
Heap Ref = 0
X
Stack Ref = 1
Y
exposed
Heap Ref = 0
Heap Ref = 2
Heap Ref = 1
Stack Ref = 0
Stack Ref = 0
Stack Ref = 1
e1
h2
h3
25
Locking and Unlocking
Locking\Unlocking by using the reference counters
• Lock object when
– its stack counter becomes positive
• Unlock object when
– its stack counter becomes 0
– not part of a forest violation (according the heap
counter)
26
Multiple Trees
void Move(Tree X, Tree Y) {
…
void Move(Tree X, Tree Y) {
{
if( address(X) <= address(Y) )
{ lock(X); lock(Y); }
else
{ lock(Y); lock(X); }
…
Code that locks pointed
objects in a fixed order
27
Performance Evaluation
• Add fine grain locking to several data structures
– 2 balanced search trees (Treap, Red-Black Tree)
– Self Adjusting Heap (Skew Heap)
– 2 specialized data structures
(Apriori, and Barnes-Hut)
• Runtime experiments show good scalability
– No optimization were used (a lot of room for
optimizations)
28
Automatic FGL vs. Manual FGL
Treap
Throughput (ops/msec)
Single
Manual hand-over-hand
Automatic
1800
1600
1400
1200
1000
800
600
400
200
0
1
2
4
Threads
6
8
29
Automatic FGL vs. Manual FGL
Apriori
Original hand-over-hand (manual)
Automatic
Normalized Time
120%
100%
80%
60%
40%
20%
0%
1
2
4
Threads
8
30
Summary
• A new fine-grain locking protocol for dynamic
heaps – Domination Locking
• Automatic realization for dynamic forests
– Adds fine-grain locking for red-black trees and
others
– Preliminary Performance Evaluation
• scales similarly to hand crafted locking
31
Thank You
32
Download