Berkin Ilbeyi1, Carl Friedrich Bolz-Tereick2, and Christopher Batten1
1 Cornell University, 2 Heinrich-Heine-Universität Düsseldorf
Cross-Layer Workload Characterization of Meta-Tracing JIT VMs Berkin - - PowerPoint PPT Presentation
Cross-Layer Workload Characterization of Meta-Tracing JIT VMs Berkin Ilbeyi 1 , Carl Friedrich Bolz-Tereick 2 , and Christopher Batten 1 1 Cornell University, 2 Heinrich-Heine-Universitt Dsseldorf Dynamic languages are popular S. Cass. The
1 Cornell University, 2 Heinrich-Heine-Universität Düsseldorf
2
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
2
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
3
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
3
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
4
Application: FooLang FooLang Interpreter interpret
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
4
Application: FooLang FooLang Interpreter FooLang JIT Compiler interpret compile GC VM Utilities
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
4
Application: FooLang FooLang Interpreter FooLang JIT Compiler interpret compile GC VM Utilities
Generic JIT Compiler GC VM Utilities
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
4
Application: FooLang FooLang Interpreter FooLang JIT Compiler interpret compile GC VM Utilities
Application: FooLang FooLang Interpreter Generic JIT Compiler interpret compile GC VM Utilities
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
4
Application: FooLang FooLang Interpreter FooLang JIT Compiler interpret compile GC VM Utilities
Application: FooLang FooLang Interpreter Generic JIT Compiler interpret compile GC VM Utilities Application: Bar Bar Interpreter interpret
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
4
Application: FooLang FooLang Interpreter FooLang JIT Compiler interpret compile GC VM Utilities
Application: FooLang FooLang Interpreter Generic JIT Compiler interpret compile GC VM Utilities
Application: Bar Bar Interpreter interpret
Meta-JIT Compiler
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
5
def max(a, b): if a > b: return a else: return b
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
5
def max(a, b): if a > b: return a else: return b guard_type(a, int) guard_type(b, int) c = int_gt(a, b) guard_true(c) return(a)
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
guard_type(a, int) guard_type(b, int) c = int_gt(a, b) jump_if_false(c, L1) return(a) L1: return(b)
5
def max(a, b): if a > b: return a else: return b guard_type(a, int) guard_type(b, int) c = int_gt(a, b) guard_true(c) return(a)
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
guard_type(a, int) guard_type(b, int) c = int_gt(a, b) jump_if_false(c, L1) return(a) L1: return(b)
5
def max(a, b): if a > b: return a else: return b guard_type(a, int) guard_type(b, int) c = int_gt(a, b) guard_true(c) return(a)
return(b)
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
guard_type(a, int) guard_type(b, int) c = int_gt(a, b) jump_if_false(c, L1) return(a) L1: return(b)
5
def max(a, b): if a > b: return a else: return b guard_type(a, int) guard_type(b, int) c = int_gt(a, b) guard_true(c) return(a)
return(b)
guard_type(a, float) guard_type(b, float) c = float_gt(a, b) guard_true(c) return(a)
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
guard_type(a, int) guard_type(b, int) c = int_gt(a, b) jump_if_false(c, L1) return(a) L1: return(b)
5
def max(a, b): if a > b: return a else: return b guard_type(a, int) guard_type(b, int) c = int_gt(a, b) guard_true(c) return(a)
return(b)
guard_type(a, float) guard_type(b, float) c = float_gt(a, b) guard_true(c) return(a)
i = is_type(a, int) jump_if_false(i, L2) guard_type(b, int) c = int_gt(a, b) jump_if_false(c, L1) return(a) L1: return(b) L2: guard_type(a, float) guard_type(b, float) c = float_gt(a, b) jump_if_false(c, L3) return(a) L3: return(b)
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
6
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
6
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
6
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
6
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
7
Application: FooLang
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
7
Application: FooLang ... b += a ...
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
7
Application: FooLang Application: Bytecode compile ... b += a ...
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
7
Application: FooLang Application: Bytecode compile ... b += a ... ... 21 LOAD_FAST 1 (b) 24 LOAD_FAST 0 (a) 27 INPLACE_ADD 28 STORE_FAST 1 (b) ...
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
7
Application: FooLang Application: Bytecode Interpreter: Python compile interpret ... b += a ... ... 21 LOAD_FAST 1 (b) 24 LOAD_FAST 0 (a) 27 INPLACE_ADD 28 STORE_FAST 1 (b) ...
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
7
Application: FooLang Application: Bytecode Interpreter: Python compile interpret ... b += a ... ... 21 LOAD_FAST 1 (b) 24 LOAD_FAST 0 (a) 27 INPLACE_ADD 28 STORE_FAST 1 (b) ... while True: bc = bcs[bci] bci += bc.length if bc.type == INPLACE_ADD: v1 = stack.pop() v2 = stack.pop() if (type(v1) == int and type(v2) == int): stack.push(v1 + v2) elif ... elif bc.type == LOAD_FAST: stack.push(local[bc.varnum]) ...
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
7
Application: FooLang Application: Bytecode Interpreter: Python compile interpret ... b += a ... ... 21 LOAD_FAST 1 (b) 24 LOAD_FAST 0 (a) 27 INPLACE_ADD 28 STORE_FAST 1 (b) ... while True: bc = bcs[bci] bci += bc.length if bc.type == INPLACE_ADD: v1 = stack.pop() v2 = stack.pop() if (type(v1) == int and type(v2) == int): stack.push(v1 + v2) elif ... elif bc.type == LOAD_FAST: stack.push(local[bc.varnum]) ... Interpreter: Bytecode compile
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
7
Application: FooLang Application: Bytecode Interpreter: Python compile interpret ... b += a ... ... 21 LOAD_FAST 1 (b) 24 LOAD_FAST 0 (a) 27 INPLACE_ADD 28 STORE_FAST 1 (b) ... while True: bc = bcs[bci] bci += bc.length if bc.type == INPLACE_ADD: v1 = stack.pop() v2 = stack.pop() if (type(v1) == int and type(v2) == int): stack.push(v1 + v2) elif ... elif bc.type == LOAD_FAST: stack.push(local[bc.varnum]) ... Interpreter: Bytecode compile Interpreter Interpreter interpret
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
8
Application: Python Application: Bytecode compile
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
8
Application: Python Application: Bytecode compile Interpreter: RPython
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
8
Application: Python Application: Bytecode compile Interpreter: RPython Framework: RPython
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
8
Application: Python Application: Bytecode compile Interpreter: RPython Framework: RPython Interpreter + Framework: C translate
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
8
Application: Python Application: Bytecode PyPy: Binary compile interpret Interpreter: RPython Framework: RPython Interpreter + Framework: C compile translate
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
8
Application: Python Application: Bytecode PyPy: Binary compile interpret Interpreter: RPython Framework: RPython Interpreter + Framework: C compile translate Meta-trace: JIT IR JIT-ed code: Binary assemble trace and optimize
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
9
... 21 LOAD_FAST 1 (b) 24 LOAD_FAST 0 (a) 27 INPLACE_ADD 28 STORE_FAST 1 (b) ... while True: bc = bcs[bci] bci += bc.length if bc.type == INPLACE_ADD: v1 = stack.pop() v2 = stack.pop() if (type(v1) == int and type(v2) == int): stack.push(v1 + v2) elif ... elif bc.type == LOAD_FAST: stack.push(local[bc.varnum]) ...
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
9
... 21 LOAD_FAST 1 (b) 24 LOAD_FAST 0 (a) 27 INPLACE_ADD 28 STORE_FAST 1 (b) ... while True: bc = bcs[bci] bci += bc.length if bc.type == INPLACE_ADD: v1 = stack.pop() v2 = stack.pop() if (type(v1) == int and type(v2) == int): stack.push(v1 + v2) elif ... elif bc.type == LOAD_FAST: stack.push(local[bc.varnum]) ...
...
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
9
... 21 LOAD_FAST 1 (b) 24 LOAD_FAST 0 (a) 27 INPLACE_ADD 28 STORE_FAST 1 (b) ... while True: bc = bcs[bci] bci += bc.length if bc.type == INPLACE_ADD: v1 = stack.pop() v2 = stack.pop() if (type(v1) == int and type(v2) == int): stack.push(v1 + v2) elif ... elif bc.type == LOAD_FAST: stack.push(local[bc.varnum]) ...
...
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
9
... 21 LOAD_FAST 1 (b) 24 LOAD_FAST 0 (a) 27 INPLACE_ADD 28 STORE_FAST 1 (b) ... while True: bc = bcs[bci] bci += bc.length if bc.type == INPLACE_ADD: v1 = stack.pop() v2 = stack.pop() if (type(v1) == int and type(v2) == int): stack.push(v1 + v2) elif ... elif bc.type == LOAD_FAST: stack.push(local[bc.varnum]) ...
...
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
9
... 21 LOAD_FAST 1 (b) 24 LOAD_FAST 0 (a) 27 INPLACE_ADD 28 STORE_FAST 1 (b) ... while True: bc = bcs[bci] bci += bc.length if bc.type == INPLACE_ADD: v1 = stack.pop() v2 = stack.pop() if (type(v1) == int and type(v2) == int): stack.push(v1 + v2) elif ... elif bc.type == LOAD_FAST: stack.push(local[bc.varnum]) ...
... p1 = getarrayitem(p0, 1)
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
9
... 21 LOAD_FAST 1 (b) 24 LOAD_FAST 0 (a) 27 INPLACE_ADD 28 STORE_FAST 1 (b) ... while True: bc = bcs[bci] bci += bc.length if bc.type == INPLACE_ADD: v1 = stack.pop() v2 = stack.pop() if (type(v1) == int and type(v2) == int): stack.push(v1 + v2) elif ... elif bc.type == LOAD_FAST: stack.push(local[bc.varnum]) ...
... p1 = getarrayitem(p0, 1)
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
9
... 21 LOAD_FAST 1 (b) 24 LOAD_FAST 0 (a) 27 INPLACE_ADD 28 STORE_FAST 1 (b) ... while True: bc = bcs[bci] bci += bc.length if bc.type == INPLACE_ADD: v1 = stack.pop() v2 = stack.pop() if (type(v1) == int and type(v2) == int): stack.push(v1 + v2) elif ... elif bc.type == LOAD_FAST: stack.push(local[bc.varnum]) ...
... p1 = getarrayitem(p0, 1) p2 = getarrayitem(p0, 0)
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
9
... 21 LOAD_FAST 1 (b) 24 LOAD_FAST 0 (a) 27 INPLACE_ADD 28 STORE_FAST 1 (b) ... while True: bc = bcs[bci] bci += bc.length if bc.type == INPLACE_ADD: v1 = stack.pop() v2 = stack.pop() if (type(v1) == int and type(v2) == int): stack.push(v1 + v2) elif ... elif bc.type == LOAD_FAST: stack.push(local[bc.varnum]) ...
... p1 = getarrayitem(p0, 1) p2 = getarrayitem(p0, 0)
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
9
... 21 LOAD_FAST 1 (b) 24 LOAD_FAST 0 (a) 27 INPLACE_ADD 28 STORE_FAST 1 (b) ... while True: bc = bcs[bci] bci += bc.length if bc.type == INPLACE_ADD: v1 = stack.pop() v2 = stack.pop() if (type(v1) == int and type(v2) == int): stack.push(v1 + v2) elif ... elif bc.type == LOAD_FAST: stack.push(local[bc.varnum]) ...
... p1 = getarrayitem(p0, 1) p2 = getarrayitem(p0, 0)
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
9
... 21 LOAD_FAST 1 (b) 24 LOAD_FAST 0 (a) 27 INPLACE_ADD 28 STORE_FAST 1 (b) ... while True: bc = bcs[bci] bci += bc.length if bc.type == INPLACE_ADD: v1 = stack.pop() v2 = stack.pop() if (type(v1) == int and type(v2) == int): stack.push(v1 + v2) elif ... elif bc.type == LOAD_FAST: stack.push(local[bc.varnum]) ...
... p1 = getarrayitem(p0, 1) p2 = getarrayitem(p0, 0) guard_class(p1, int) guard_class(p2, int)
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
9
... 21 LOAD_FAST 1 (b) 24 LOAD_FAST 0 (a) 27 INPLACE_ADD 28 STORE_FAST 1 (b) ... while True: bc = bcs[bci] bci += bc.length if bc.type == INPLACE_ADD: v1 = stack.pop() v2 = stack.pop() if (type(v1) == int and type(v2) == int): stack.push(v1 + v2) elif ... elif bc.type == LOAD_FAST: stack.push(local[bc.varnum]) ...
... p1 = getarrayitem(p0, 1) p2 = getarrayitem(p0, 0) guard_class(p1, int) guard_class(p2, int) i3 = getfield(p1, intval) i4 = getfield(p2, intval)
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
9
... 21 LOAD_FAST 1 (b) 24 LOAD_FAST 0 (a) 27 INPLACE_ADD 28 STORE_FAST 1 (b) ... while True: bc = bcs[bci] bci += bc.length if bc.type == INPLACE_ADD: v1 = stack.pop() v2 = stack.pop() if (type(v1) == int and type(v2) == int): stack.push(v1 + v2) elif ... elif bc.type == LOAD_FAST: stack.push(local[bc.varnum]) ...
... p1 = getarrayitem(p0, 1) p2 = getarrayitem(p0, 0) guard_class(p1, int) guard_class(p2, int) i3 = getfield(p1, intval) i4 = getfield(p2, intval) i5 = int_add_ovf(i3, i4) guard_no_overflow() ...
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
9
... 21 LOAD_FAST 1 (b) 24 LOAD_FAST 0 (a) 27 INPLACE_ADD 28 STORE_FAST 1 (b) ... while True: bc = bcs[bci] bci += bc.length if bc.type == INPLACE_ADD: v1 = stack.pop() v2 = stack.pop() if (type(v1) == int and type(v2) == int): stack.push(v1 + v2) elif ... elif bc.type == LOAD_FAST: stack.push(local[bc.varnum]) ...
... p1 = getarrayitem(p0, 1) p2 = getarrayitem(p0, 0) guard_class(p1, int) guard_class(p2, int) i3 = getfield(p1, intval) i4 = getfield(p2, intval) i5 = int_add_ovf(i3, i4) guard_no_overflow() ...
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
10
Application: Python Application: Bytecode PyPy: Binary compile interpret Interpreter: RPython Framework: RPython Interpreter + Application: C compile translate Meta-trace: JIT IR JIT-ed code: Binary assemble trace and optimize
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
10
Application: Python Application: Bytecode PyPy: Binary compile interpret Interpreter: RPython Framework: RPython Interpreter + Application: C compile translate Meta-trace: JIT IR JIT-ed code: Binary assemble trace and optimize
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
10
Application: Python Application: Bytecode PyPy: Binary compile interpret Interpreter: RPython Framework: RPython Interpreter + Application: C compile translate Meta-trace: JIT IR JIT-ed code: Binary assemble trace and optimize
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
10
Application: Python Application: Bytecode PyPy: Binary compile interpret Interpreter: RPython Framework: RPython Interpreter + Application: C compile translate Meta-trace: JIT IR JIT-ed code: Binary assemble trace and optimize
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
10
Application: Python Application: Bytecode PyPy: Binary compile interpret Interpreter: RPython Framework: RPython Interpreter + Application: C compile translate Meta-trace: JIT IR JIT-ed code: Binary assemble trace and optimize
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
10
Application: Python Application: Bytecode PyPy: Binary compile interpret Interpreter: RPython Framework: RPython Interpreter + Application: C compile translate Meta-trace: JIT IR JIT-ed code: Binary assemble trace and optimize
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
10
Application: Python Application: Bytecode PyPy: Binary compile interpret Interpreter: RPython Framework: RPython Interpreter + Application: C compile translate Meta-trace: JIT IR JIT-ed code: Binary assemble trace and optimize
Dynamic Binary Instrumentation
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
10
Application: Python Application: Bytecode PyPy: Binary compile interpret Interpreter: RPython Framework: RPython Interpreter + Application: C compile translate Meta-trace: JIT IR JIT-ed code: Binary assemble trace and optimize
Dynamic Binary Instrumentation
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
11
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
12
5 10 15 20 25 30 richards crypto_pyaes chaos telco spectral-norm django twisted_iteration spitfire_cstringio raytrace-simple hexiom2 float ai nbody_modified twisted_pb fannkuch genshi_text pyflate-fast bm_mako twisted_names json_bench genshi_xml bm_chameleon pypy_interp twisted_tcp html5lib meteor-contest sympy_sum spitfire spambayes rietveld deltablue eparse sympy_expand slowspitfire sympy_integrate pidigits bm_mdp sympy_str
51.2 30.2 Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
13
1 2 3 4 5 6 7 8 9 10 11 12 binarytrees chameneosredux fannkuchredux fasta knucleotide mandelbrot meteor nbody pidigits regexdna revcomp spectralnorm threadring PyPy speedup
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
13
1 2 3 4 5 6 7 8 9 10 11 12 binarytrees chameneosredux fannkuchredux fasta knucleotide mandelbrot meteor nbody pidigits regexdna revcomp spectralnorm threadring PyPy speedup 0.5 1 1.5 2 binarytrees fannkuchredux fasta mandelbrot meteor nbody pidigits revcomp spectralnorm Pycket speedup
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
14
calls to AOT funs JIT GC deoptimization tracing & opt interpreter 0 2B 4B 6B 8B 10B instructions
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
14
calls to AOT funs JIT GC deoptimization tracing & opt interpreter calls to AOT funs JIT GC deoptimization tracing & opt interpreter 0 2B 4B 6B 8B 10B instructions 0 2B 4B 6B 8B 10B instructions
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
15
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
16
0.25 0.5 0.75 1
JIT + JIT call to AOT
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
17
while True: ... memcpy(d, s, n) ... def memcpy(dest, src, n): i = 0 while i < n: dest[i] = src[i] i += 1
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
17
while True: ... memcpy(d, s, n) ... def memcpy(dest, src, n): i = 0 while i < n: dest[i] = src[i] i += 1
...
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
17
while True: ... memcpy(d, s, n) ... def memcpy(dest, src, n): i = 0 while i < n: dest[i] = src[i] i += 1
... guard_gt(i0, 0) i3 = getarrayitem(p1, 0) setarrayitem(p2, 0, i3)
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
17
while True: ... memcpy(d, s, n) ... def memcpy(dest, src, n): i = 0 while i < n: dest[i] = src[i] i += 1
... guard_gt(i0, 0) i3 = getarrayitem(p1, 0) setarrayitem(p2, 0, i3) guard_gt(i0, 1) i4 = getarrayitem(p1, 1) setarrayitem(p2, 1, i4)
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
17
while True: ... memcpy(d, s, n) ... def memcpy(dest, src, n): i = 0 while i < n: dest[i] = src[i] i += 1
... guard_gt(i0, 0) i3 = getarrayitem(p1, 0) setarrayitem(p2, 0, i3) guard_gt(i0, 1) i4 = getarrayitem(p1, 1) setarrayitem(p2, 1, i4) guard_gt(i0, 2) i5 = getarrayitem(p1, 2) setarrayitem(p2, 2, i5) ...
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
18
setobject.get_storage_from_list
rordereddict.ll_call_lookup_function
runicode.unicode_encode_ucs1_helper
_pypyjson.raw_encode_basestring_ascii
pow
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
19
0.25 0.5 0.75 1
JIT JIT call to AOT functions
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
20
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
20
0 2B 4B 6B 8B 10B instructions
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
20
0 2B 4B 6B 8B 10B instructions
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
20
0 2B 4B 6B 8B 10B instructions 0 2B 4B 6B 8B 10B instructions
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
20
0 2B 4B 6B 8B 10B instructions 0 2B 4B 6B 8B 10B instructions
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
20
0 2B 4B 6B 8B 10B instructions 0 2B 4B 6B 8B 10B instructions 0 2B 4B 6B 8B 10B instructions
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
21
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
21
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
21
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
21
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
22
5 10 15 20 25 30 binarytrees chameneosredux fannkuchredux fasta knucleotide mandelbrot meteor nbody pidigits regexdna revcomp spectralnorm threadring PyPy slowdown
1374 31 Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
22
5 10 15 20 25 30 binarytrees chameneosredux fannkuchredux fasta knucleotide mandelbrot meteor nbody pidigits regexdna revcomp spectralnorm threadring PyPy slowdown 2 4 6 8 10 12 binarytrees fannkuchredux fasta mandelbrot meteor nbody pidigits revcomp spectralnorm Pycket slowdown
1374 31 Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
23
0.25 0.5 0.75 1
JIT JIT call to AOT functions
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
24
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
24
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
24
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
25
0.25 0.5 0.75 1
JIT JIT call to AOT functions
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
26
0.25 0.5 0.75 1
Interpreter
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
27
0.2 0.4 0.6 0.8 1 1.2 richards crypto_pyaes chaos telco spectral-norm django twisted_iteration spitfire_cstringio raytrace-simple hexiom2 float ai nbody_modified twisted_pb fannkuch genshi_text pyflate-fast bm_mako twisted_names json_bench genshi_xml bm_chameleon pypy_interp twisted_tcp html5lib meteor-contest sympy_sum spitfire spambayes rietveld deltablue eparse sympy_expand slowspitfire sympy_integrate pidigits bm_mdp sympy_str
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
28
0.25 0.5 0.75 1
Tracing & optimization
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
29
0.25 0.5 0.75 1
Deoptimization
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
30
0.25 0.5 0.75 1
Garbage collection
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
31
0.25 0.5 0.75 1
Interpreter Tracing & optimization Deoptimization Garbage collection
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
32
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
33 0.375 0.75 1.125 1.5 1.875 2.25 b i n a r y t r e e s c h a m e n e
r e d u x f a n n k u c h r e d u x f a s t a k n u c l e
i d e m a n d e l b r
m e t e
n b
y p i d i g i t s r e g e x d n a r e v c
p s p e c t r a l n
m t h r e a d r i n g C/C++ IPC PyPy IPC Pycket IPC
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
33 0.375 0.75 1.125 1.5 1.875 2.25 b i n a r y t r e e s c h a m e n e
r e d u x f a n n k u c h r e d u x f a s t a k n u c l e
i d e m a n d e l b r
m e t e
n b
y p i d i g i t s r e g e x d n a r e v c
p s p e c t r a l n
m t h r e a d r i n g C/C++ IPC PyPy IPC Pycket IPC
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
34
JIT GC deopt trace interp
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
35
0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 Interp Trace Deopt GC JIT C/C++
IPC
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
35
0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 Interp Trace Deopt GC JIT C/C++
IPC
0.05 0.1 0.15 0.2 Interp Trace Deopt GC JIT C/C++
Branch per instruction
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
35
0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 Interp Trace Deopt GC JIT C/C++
IPC
0.05 0.1 0.15 0.2 Interp Trace Deopt GC JIT C/C++
Branch per instruction
1 2 3 4 5 6 7 8 9 10 11 Interp Trace Deopt GC JIT C/C++
Branch MPKI
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
36
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
36
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
36
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
36
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
36
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
36
Motivation • Meta-tracing • PyPy >> CPython • PyPy << C
1 Cornell University, 2 Heinrich-Heine-Universität Düsseldorf