Self-Adjusting Stack Machines Matthew A. Hammer Georg Neis Yan Chen Umut A. Acar Max Planck Institute for Software Systems OOPSLA 2011 — October 27, 2011 Portland, Oregon, USA
Static Computation Versus Dynamic Computation Static Computation: Fixed Input Compute Fixed Output Dynamic Computation: Changing Input Compute Changing Output Read Write Update Changes Updates Matthew A. Hammer Self-Adjusting Stack Machines 2
Dynamic Data is Everywhere Software systems often consume/produce dynamic data Reactive Systems Scientific Analysis of Simulation Internet data Matthew A. Hammer Self-Adjusting Stack Machines 3
Tractability Requires Dynamic Computations Changing Input Compute Changing Output Static Case (Re-evaluation “from scratch”) compute 1 sec # of changes 1 million Total time 11.6 days Matthew A. Hammer Self-Adjusting Stack Machines 4
Tractability Requires Dynamic Computations Changing Input Compute Changing Output Read Write Update Changes Updates Static Case Dynamic Case (Re-evaluation “from scratch”) (Uses update mechanism) compute 1 sec compute 10 sec 1 × 10 − 3 sec # of changes 1 million update Total time 11.6 days # of changes 1 million Total time 16.7 minutes Speedup 1000x Matthew A. Hammer Self-Adjusting Stack Machines 4
Dynamic Computations can be Hand-Crafted As an input sequence changes, maintain a sorted output. Changing Input Changing Output compute 1,7,3,6,5,2,4 1,2,3,4,5,6,7 1,7,3,6 / ,5,2,4 update 1,2,3,4,5,6 / ,7 Remove 6 Reinsert 6, 1,7,3, 6 ,5,2 / ,4 update 1,2 / ,3,4,5, 6 ,7 Remove 2 A binary search tree would suffice here (e.g., a splay tree) What about more exotic/complex computations? Matthew A. Hammer Self-Adjusting Stack Machines 5
How to Program Dynamic Computations? Can this programming be systematic? What are the right abstractions? 1. How to describe dynamic computations? ◮ Usability : Are these descriptions easy to write? ◮ Generality : How much can they describe? 2. How to implement these descriptions? ◮ Efficiency : Are updates faster than re-evaluation? ◮ Consistency : Do updates provide the correct result? Matthew A. Hammer Self-Adjusting Stack Machines 6
In Self-Adjusting Computation , Ordinary programs describe dynamic computations. Compiler C Target + C Source Run-time Self-Adjusting Program The self-adjusting program : 1. Computes initial output from initial input 2. Automatically updates output when input changes Matthew A. Hammer Self-Adjusting Stack Machines 7
Self-Adjusting Programs Input Compute Output Read Write Read Write Trace Changes Updates Update ◮ Self-adjusting program maintains dynamic dependencies in an execution trace. ◮ Key Idea : Reusing traces � efficient update Matthew A. Hammer Self-Adjusting Stack Machines 8
Challenges Existing work targets functional languages : ◮ Library support for SML and Haskell ◮ DeltaML extends MLton SML compiler Our work targets low-level languages (e.g., C) ◮ stack-based ◮ imperative ◮ no strong type system ◮ no automatic memory management Matthew A. Hammer Self-Adjusting Stack Machines 9
Challenges Low-Level Self-Adj. Computation Efficient update � complex resource interactions : ◮ execution trace, call stack, memory manager Input Compute Output Read Write Read Write Trace Changes Updates Update Matthew A. Hammer Self-Adjusting Stack Machines 10
Challenges Low-Level Self-Adj. Computation Efficient update � complex resource interactions : ◮ execution trace, call stack, memory manager Input Compute Output Read Write Read Write Trace Changes Updates Update Matthew A. Hammer Self-Adjusting Stack Machines 10
Challenges Low-Level Self-Adj. Computation Efficient update � complex resource interactions : ◮ execution trace, call stack, memory manager � make new trace, � search old trace code revaluation found change found match change propagation � repair + edit � old trace Matthew A. Hammer Self-Adjusting Stack Machines 10
Example: Dynamic Expression Trees Objective : As tree changes, maintain its valuation + + − − − + + + − 0 5 6 0 5 3 4 3 4 5 6 (( 3 + 4 ) − 0 ) + ( 5 − 6 ) = 6 (( 3 + 4 )− 0 )+(( 5 − 6 )+ 5 ) = 11 Matthew A. Hammer Self-Adjusting Stack Machines 11
Example: Dynamic Expression Trees Objective : As tree changes, maintain its valuation + + − − − + + + − 0 5 6 0 5 3 4 3 4 5 6 (( 3 + 4 ) − 0 ) + ( 5 − 6 ) = 6 (( 3 + 4 )− 0 )+(( 5 − 6 )+ 5 ) = 11 Consistency : Output is correct valuation Efficiency : Update time is O ( # affected intermediate results ) Matthew A. Hammer Self-Adjusting Stack Machines 11
Expression Tree Evaluation in C 1 typedef struct node s* node t; 2 struct node s { 3 enum { LEAF, BINOP } tag; 4 union { int leaf; 5 struct { enum { PLUS, MINUS } op; 6 node t left, right; 7 } binop; 8 } u; } 1 int eval (node t root) { if (root->tag == LEAF) 2 return root->u.leaf; 3 else { 4 int l = eval (root->u.binop.left); 5 int r = eval (root->u.binop.right); 6 if (root->u.binop.op == PLUS) return (l + r); 7 else return (l - r); 8 } } 9 Matthew A. Hammer Self-Adjusting Stack Machines 12
The Stack “Shapes” the Computation int eval (node t root) { if (root->tag == LEAF) return root->u.leaf; else { int l = eval (root->u.binop.left); int r = eval (root->u.binop.right); if (root->u.binop.op == PLUS) return (l + r); else return (l - r); } } Stack usage breaks computation into three parts : Matthew A. Hammer Self-Adjusting Stack Machines 13
The Stack “Shapes” the Computation int eval (node t root) { if (root->tag == LEAF) return root->u.leaf; else { int l = eval (root->u.binop.left); int r = eval (root->u.binop.right); if (root->u.binop.op == PLUS) return (l + r); else return (l - r); } } Stack usage breaks computation into three parts : ◮ Part A : Return value if LEAF Otherwise, evaluate BINOP , starting with left child Matthew A. Hammer Self-Adjusting Stack Machines 13
The Stack “Shapes” the Computation int eval (node t root) { if (root->tag == LEAF) return root->u.leaf; else { int l = eval (root->u.binop.left); int r = eval (root->u.binop.right); if (root->u.binop.op == PLUS) return (l + r); else return (l - r); } } Stack usage breaks computation into three parts : ◮ Part A : Return value if LEAF Otherwise, evaluate BINOP , starting with left child ◮ Part B : Evaluate the right child Matthew A. Hammer Self-Adjusting Stack Machines 13
The Stack “Shapes” the Computation int eval (node t root) { if (root->tag == LEAF) return root->u.leaf; else { int l = eval (root->u.binop.left); int r = eval (root->u.binop.right); if (root->u.binop.op == PLUS) return (l + r); else return (l - r); } } Stack usage breaks computation into three parts : ◮ Part A : Return value if LEAF Otherwise, evaluate BINOP , starting with left child ◮ Part B : Evaluate the right child ◮ Part C : Apply BINOP to intermediate results; return Matthew A. Hammer Self-Adjusting Stack Machines 13
Dynamic Execution Traces Input Tree + − − + 0 5 6 3 4 Execution Trace A + B + C + A − B − C − A − B − C − A + B + C + A 0 A 5 A 6 A 3 A 4 Matthew A. Hammer Self-Adjusting Stack Machines 14
How to Update the Output? Original Input Changed Input + + − − − + + 0 5 6 + 0 − 5 3 4 3 4 5 6 Goals: ◮ Consistency : Respect the (static) program’s meaning ◮ Efficiency : Reuse original computation when possible Matthew A. Hammer Self-Adjusting Stack Machines 15
How to Update the Output? Original Input Changed Input + + − − − + + 0 5 6 + 0 − 5 3 4 3 4 5 6 Goals: ◮ Consistency : Respect the (static) program’s meaning ◮ Efficiency : Reuse original computation when possible Idea: Transform the first trace into second trace Matthew A. Hammer Self-Adjusting Stack Machines 15
+ − + + − 0 5 3 4 5 6 Affected/Re-eval Affected/Re-eval A + B + C + A − B − C − A + B + C + A + B + C + A 0 A − B − C − A 5 A 3 A 4 A 5 A 6 New Evaluation Unaffected/Reuse Unaffected/Reuse Matthew A. Hammer Self-Adjusting Stack Machines 16
Before Update A + B + C + A − B − C − A − B − C − A + B + C + A 0 A 5 A 6 A 3 A 4 After Update A + B + C + A − B − C − A + B + C + A + B + C + A − B − C − A 0 A 5 A 3 A 4 A 5 A 6 Matthew A. Hammer Self-Adjusting Stack Machines 17
How to Program Dynamic Computations? 1. How to describe dynamic computations? � Usability : Are these descriptions easy to write? � Generality : How much can they describe? 2. How to implement this description? ? Correctness : Do updates provide the correct result? ? Efficiency : Are updates faster than re-evaluation? Matthew A. Hammer Self-Adjusting Stack Machines 18
Overview of Formal Semantics ◮ IL: Intermediate language for C-like programs ◮ IL has instructions for: ◮ Mutable memory: alloc , read , write ◮ Managing local state via a stack: push , pop ◮ Saving/restoring local state: memo , update Matthew A. Hammer Self-Adjusting Stack Machines 19
Recommend
More recommend