Self-Adjusting Stack Machines Matthew A. Hammer Georg Neis Yan - - PowerPoint PPT Presentation

self adjusting stack machines
SMART_READER_LITE
LIVE PREVIEW

Self-Adjusting Stack Machines Matthew A. Hammer Georg Neis Yan - - PowerPoint PPT Presentation

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


slide-1
SLIDE 1

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

slide-2
SLIDE 2

Static Computation Versus Dynamic Computation

Static Computation: Fixed Input Compute Fixed Output Dynamic Computation: Changing Input Compute Changing Output Read Changes Update Write Updates

Matthew A. Hammer Self-Adjusting Stack Machines 2

slide-3
SLIDE 3

Dynamic Data is Everywhere

Software systems often consume/produce dynamic data Scientific Simulation Reactive Systems Analysis of Internet data

Matthew A. Hammer Self-Adjusting Stack Machines 3

slide-4
SLIDE 4

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

slide-5
SLIDE 5

Tractability Requires Dynamic Computations

Changing Input Compute Changing Output Read Changes Update Write Updates Static Case (Re-evaluation “from scratch”) compute 1 sec # of changes 1 million Total time 11.6 days Dynamic Case (Uses update mechanism) compute 10 sec update 1 × 10−3 sec # of changes 1 million Total time 16.7 minutes Speedup 1000x

Matthew A. Hammer Self-Adjusting Stack Machines 4

slide-6
SLIDE 6

Dynamic Computations can be Hand-Crafted

As an input sequence changes, maintain a sorted output. 1,7,3,6,5,2,4 Changing Input compute 1,2,3,4,5,6,7 Changing Output 1,7,3,6 /,5,2,4 Remove 6 update 1,2,3,4,5,6 /,7 1,7,3,6,5,2 /,4 Reinsert 6, Remove 2 update 1,2 /,3,4,5,6,7 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

slide-7
SLIDE 7

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

slide-8
SLIDE 8

In Self-Adjusting Computation, Ordinary programs describe dynamic computations. Self-Adjusting Program C Source Compiler C Target + Run-time 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

slide-9
SLIDE 9

Self-Adjusting Programs

Input Read Compute Write Output Read Changes Trace Write 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

slide-10
SLIDE 10

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

slide-11
SLIDE 11

Challenges Low-Level Self-Adj. Computation

Efficient update complex resource interactions:

◮ execution trace, call stack, memory manager

Input Read Compute Write Output Read Changes Trace Write Updates Update

Matthew A. Hammer Self-Adjusting Stack Machines 10

slide-12
SLIDE 12

Challenges Low-Level Self-Adj. Computation

Efficient update complex resource interactions:

◮ execution trace, call stack, memory manager

Input Read Compute Write Output Read Changes Trace Write Updates Update

Matthew A. Hammer Self-Adjusting Stack Machines 10

slide-13
SLIDE 13

Challenges Low-Level Self-Adj. Computation

Efficient update complex resource interactions:

◮ execution trace, call stack, memory manager

code revaluation make new trace, search old trace

  • found change

found match change propagation repair + edit

  • ld trace
  • Matthew A. Hammer

Self-Adjusting Stack Machines 10

slide-14
SLIDE 14

Example: Dynamic Expression Trees

Objective: As tree changes, maintain its valuation

+ − + 3 4 − 5 6

((3 + 4) − 0) + (5 − 6) = 6

+ − + 3 4 + − 5 6 5

((3+4)−0)+((5−6)+5) = 11

Matthew A. Hammer Self-Adjusting Stack Machines 11

slide-15
SLIDE 15

Example: Dynamic Expression Trees

Objective: As tree changes, maintain its valuation

+ − + 3 4 − 5 6

((3 + 4) − 0) + (5 − 6) = 6

+ − + 3 4 + − 5 6 5

((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

slide-16
SLIDE 16

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) { 2 if (root->tag == LEAF) 3 return root->u.leaf; 4 else { 5 int l = eval (root->u.binop.left); 6 int r = eval (root->u.binop.right); 7 if (root->u.binop.op == PLUS) return (l + r); 8 else return (l - r); 9 } }

Matthew A. Hammer Self-Adjusting Stack Machines 12

slide-17
SLIDE 17

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

slide-18
SLIDE 18

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

slide-19
SLIDE 19

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

slide-20
SLIDE 20

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

slide-21
SLIDE 21

Dynamic Execution Traces

Input Tree + − + 3 4 − 5 6 Execution Trace

A+ B+ C+ A− B− C− A− B− C− A+ B+ C+ A0 A5 A6 A3 A4

Matthew A. Hammer Self-Adjusting Stack Machines 14

slide-22
SLIDE 22

How to Update the Output?

Original Input + − + 3 4 − 5 6 Changed Input + − + 3 4 + − 5 6 5 Goals:

◮ Consistency: Respect the (static) program’s meaning ◮ Efficiency: Reuse original computation when possible

Matthew A. Hammer Self-Adjusting Stack Machines 15

slide-23
SLIDE 23

How to Update the Output?

Original Input + − + 3 4 − 5 6 Changed Input + − + 3 4 + − 5 6 5 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

slide-24
SLIDE 24

+ − + 3 4 + − 5 6 5 Unaffected/Reuse Affected/Re-eval New Evaluation Unaffected/Reuse Affected/Re-eval

A+ B+ C+ A− B− C− A+ B+ C+ A+ B+ C+ A0 A− B− C− A5 A3 A4 A5 A6

Matthew A. Hammer Self-Adjusting Stack Machines 16

slide-25
SLIDE 25

Before Update A+ B+ C+ A− B− C− A− B− C− A+ B+ C+ A0 A5 A6 A3 A4 After Update A+ B+ C+ A− B− C− A+ B+ C+ A+ B+ C+ A0 A− B− C− A5 A3 A4 A5 A6

Matthew A. Hammer Self-Adjusting Stack Machines 17

slide-26
SLIDE 26

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

slide-27
SLIDE 27

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

slide-28
SLIDE 28

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

◮ Transition semantics: two abstract stack machines:

◮ Reference machine: defines “normal” semantics ◮ Tracing machine: defines self-adjusting semantics

Can compute an output and a trace Can update output/trace when memory changes Automatically marks garbage in memory

◮ We prove that these stack machines are consistent

Matthew A. Hammer Self-Adjusting Stack Machines 19

slide-29
SLIDE 29

Consistency theorem, Part 1: No Reuse

Trace Input Tracing Machine Run (P) Output

  • Input

Reference Machine Run (P) Output Tracing machine is consistent with reference machine (when tracing machine runs “from-scratch”, with no reuse)

Matthew A. Hammer Self-Adjusting Stack Machines 20

slide-30
SLIDE 30

Consistency theorem, Part 2: Reuse vs No Reuse

Trace0 Input Tracing Machine Run (P) Trace Output

  • Input

Tracing Machine Run (P) Trace Output Tracing machine is consistent with from-scratch runs (When it reuses some existing trace Trace0)

Matthew A. Hammer Self-Adjusting Stack Machines 21

slide-31
SLIDE 31

Consistency theorem: Main result

Trace0 Trace Input Tracing Machine Run (P) Output

  • Input

Reference Machine Run (P) Output Main result uses Part 1 and Part 2 together: Tracing machine is consistent with reference machine

Matthew A. Hammer Self-Adjusting Stack Machines 22

slide-32
SLIDE 32

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 23

slide-33
SLIDE 33

Overview of Our Implementation

CEAL Compiler C Translate IL Transform IL Translate C + RT

◮ Compiler: produces C targets from C-like source code ◮ Run-time: maintains traces, performs efficient updates

Matthew A. Hammer Self-Adjusting Stack Machines 24

slide-34
SLIDE 34

Dynamic Expression Trees: From-Scratch Time

0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 250K 500K 750K Time (s) Input Size Exptrees From-Scratch Self-Adj Static

Matthew A. Hammer Self-Adjusting Stack Machines 25

slide-35
SLIDE 35

Dynamic Expression Trees: Ave Update Time

0.011 0.012 0.013 0.014 0.015 0.016 0.017 0.018 0.019 0.020 0.021 0.022 250K 500K 750K Time (ms) Input Size Exptrees Ave Update Self-Adj

Matthew A. Hammer Self-Adjusting Stack Machines 26

slide-36
SLIDE 36

Dynamic Expression Trees: Speed up

0.0 x 100 5.0 x 103 1.0 x 104 1.5 x 104 2.0 x 104 2.5 x 104 250K 500K 750K Speedup Input Size Exptrees Speedup Self-Adj

Matthew A. Hammer Self-Adjusting Stack Machines 27

slide-37
SLIDE 37

Summary of Empirical Results

Benchmark N Initial Overhead Speed-up (Compute / Static) (Static / Update) exptrees 106 8.5 1.4 × 104 map 106 18.4 3.0 × 104 reverse 106 18.4 3.8 × 104 filter 106 10.7 4.9 × 104 sum 106 9.6 1.5 × 103 minimum 106 7.7 1.4 × 104 quicksort 105 8.2 6.9 × 102 mergesort 105 7.2 7.8 × 102 quickhull 105 3.7 2.2 × 103 diameter 105 3.4 1.8 × 103 distance 105 3.4 7.9 × 102

Matthew A. Hammer Self-Adjusting Stack Machines 28

slide-38
SLIDE 38

Our Contributions

A consistent self-adjusting semantics for low-level programs

Matthew A. Hammer Self-Adjusting Stack Machines 29

slide-39
SLIDE 39

Our Contributions

A consistent self-adjusting semantics for low-level programs Our abstract machine semantics

◮ Describes trace editing & memory management

implementation of run-time system

◮ But requires programs with a particular structure

implementation of compiler transformations

Matthew A. Hammer Self-Adjusting Stack Machines 29

slide-40
SLIDE 40

Our Contributions

A consistent self-adjusting semantics for low-level programs Our abstract machine semantics

◮ Describes trace editing & memory management

implementation of run-time system

◮ But requires programs with a particular structure

implementation of compiler transformations Our intermediate language is low-level, yet abstract

◮ orthogonal annotations for self-adjusting behavior ◮ no type system needed

implementation of C front end

Matthew A. Hammer Self-Adjusting Stack Machines 29

slide-41
SLIDE 41

Thank You! Questions?

Self-adjusting computation is a language-based technique to derive dynamic programs from static programs. Summary of contributions:

◮ A self-adjusting semantics for low-level programs.

This semantics defines self-adjusting stack machines.

◮ A compiler and run-time that implement the semantics. ◮ A front end that embeds much of C.

Matthew A. Hammer Self-Adjusting Stack Machines 30