fosdem 2016 - jruby 9000 · jruby 9000 optimizing above the jvm. me • charles oliver nutter •...
TRANSCRIPT
![Page 1: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/1.jpg)
JRuby 9000Optimizing Above the JVM
![Page 2: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/2.jpg)
Me
• Charles Oliver Nutter
• @headius
• Red Hat
• Based in Minneapolis, Minnesota
• Ten years working on JRuby (uff da!)
![Page 3: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/3.jpg)
JRuby 9000
• Optimizable intermediate representation
• Mixed mode runtime (now with tiers!)
• Lazy JIT to JVM bytecode
• byte[] strings and regular expressions
![Page 4: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/4.jpg)
Intermediate Representation
• AST to semantic representation
• Traditional compiler design
• Register machine
![Page 5: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/5.jpg)
LexicalAnalysisParsing
SemanticAnalysis
Optimization
Bytecode GenerationInterpret
AST
IR Instructions
CFG DFG ...
JRuby 1.7.x
9000+
BytecodeGenerationInterpret
![Page 6: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/6.jpg)
def foo(a, b) c = 1 d = a + cend
0 check_arity(2, 0, -1)1 a = recv_pre_reqd_arg(0)2 b = recv_pre_reqd_arg(1)3 %block = recv_closure4 thread_poll5 line_num(1)6 c = 17 line_num(2)8 %v_0 = call(:+, a, [c])9 d = copy(%v_0)10 return(%v_0)
Register-based
3 address format
IR InstructionsSemanticAnalysis
![Page 7: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/7.jpg)
-Xir.passes=LocalOptimizationPass, DeadCodeElimination
def foo(a, b) c = 1 d = a + cend
0 check_arity(2, 0, -1)1 a = recv_pre_reqd_arg(0)2 b = recv_pre_reqd_arg(1)3 %block = recv_closure4 thread_poll5 line_num(1)6 c = 17 line_num(2)8 %v_0 = call(:+, a, [c])9 d = copy(%v_0)10 return(%v_0)
Optimization
![Page 8: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/8.jpg)
-Xir.passes=LocalOptimizationPass, DeadCodeElimination
def foo(a, b) c = 1 d = a + cend
0 check_arity(2, 0, -1)1 a = recv_pre_reqd_arg(0)2 b = recv_pre_reqd_arg(1)3 %block = recv_closure4 thread_poll5 line_num(1)6 c = 17 line_num(2)8 %v_0 = call(:+, a, [c])9 d = copy(%v_0)10 return(%v_0)
Optimization
![Page 9: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/9.jpg)
-Xir.passes=LocalOptimizationPass, DeadCodeElimination
def foo(a, b) c = 1 d = a + cend
0 check_arity(2, 0, -1)1 a = recv_pre_reqd_arg(0)2 b = recv_pre_reqd_arg(1)3 %block = recv_closure4 thread_poll5 line_num(1)6 c = 17 line_num(2)8 %v_0 = call(:+, a, [c])9 d = copy(%v_0)10 return(%v_0)
Optimization
![Page 10: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/10.jpg)
def foo(a, b) c = 1 d = a + cend
0 check_arity(2, 0, -1)1 a = recv_pre_reqd_arg(0)4 thread_poll5 line_num(1)6 c = 17 line_num(2)8 %v_0 = call(:+, a, [c])9 d = copy(%v_0)10 return(%v_0)
Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
![Page 11: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/11.jpg)
def foo(a, b) c = 1 d = a + cend
0 check_arity(2, 0, -1)1 a = recv_pre_reqd_arg(0)4 thread_poll5 line_num(1)6 c = 17 line_num(2)8 %v_0 = call(:+, a, [c])9 d = copy(%v_0)10 return(%v_0)
Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
![Page 12: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/12.jpg)
def foo(a, b) c = 1 d = a + cend
0 check_arity(2, 0, -1)1 a = recv_pre_reqd_arg(0)4 thread_poll5 line_num(1)6 c = 17 line_num(2)8 %v_0 = call(:+, a, [c])9 d = copy(%v_0)10 return(%v_0)
Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
![Page 13: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/13.jpg)
def foo(a, b) c = 1 d = a + cend
0 check_arity(2, 0, -1)1 a = recv_pre_reqd_arg(0)4 thread_poll5 line_num(1)6 c = 7 line_num(2)8 %v_0 = call(:+, a, [ ])9 d = copy(%v_0)10 return(%v_0)
1
Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
![Page 14: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/14.jpg)
def foo(a, b) c = 1 d = a + cend
0 check_arity(2, 0, -1)1 a = recv_pre_reqd_arg(0)4 thread_poll5 line_num(1)7 line_num(2)8 %v_0 = call(:+, a, [1])9 d = copy(%v_0)10 return(%v_0)
Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
![Page 15: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/15.jpg)
0 check_arity(2, 0, -1)1 a = recv_pre_reqd_arg(0)4 thread_poll5 line_num(1)7 line_num(2)8 %v_0 = call(:+, a, [1])9 d = copy(%v_0)10 return(%v_0)
Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
![Page 16: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/16.jpg)
0 check_arity(2, 0, -1)1 a = recv_pre_reqd_arg(0)4 thread_poll7 line_num(2)8 %v_0 = call(:+, a, [1])9 d = copy(%v_0)10 return(%v_0)
Optimization -Xir.passes=LocalOptimizationPass, DeadCodeElimination
![Page 17: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/17.jpg)
Tiers!
• Tier 1: Simple interpreter (no passes run)
• Tier 2: Full interpreter (static optimization)
• Tier 3: Full interpreter (profiled optz)
• Tier 4: JVM bytecode
• Tiers 5+: Whatever JVM does from there
![Page 18: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/18.jpg)
Why Not Truffle?
• Startup and memory use are worse
• No integration with other JVM langs yet
• We still want to target JVM
• It's not ready yet!
![Page 19: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/19.jpg)
Red/black tree benchmark
0
2.25
4.5
6.75
9
JRuby int JRuby no indy JRuby with indyJRuby+Truffle CRuby 2.3
![Page 20: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/20.jpg)
Red/black tree benchmark
0
0.75
1.5
2.25
3
JRuby no indy JRuby with indy JRuby+TruffleCRuby 2.3
![Page 21: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/21.jpg)
Recent Wins
• JITable blocks
• define_method performance
• Reduced-cost transient exceptions
![Page 22: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/22.jpg)
Block Jitting
• JRuby 1.7 only jitted methods
• Not free-standing procs/lambdas
• Not define_method blocks
• Easier to do now with 9000's IR
• Blocks JIT as of 9.0.4.0
![Page 23: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/23.jpg)
class Foo define_method :test do self endend
loop do puts Benchmark.measure { 1_000_000.times { call some method }}end
![Page 24: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/24.jpg)
Block JittingPerformance of define_method in loaded file
0k iters/s
750k iters/s
1500k iters/s
2250k iters/s
3000k iters/s
MRI JRuby 9.0.1.0 JRuby 9.0.4.0
normal method define_method method
ruby -e 'load "bench_define_method.rb"'
![Page 25: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/25.jpg)
define_method
Convenient for metaprogramming,but blocks have more overhead than methods.
define_method(:add) do |a, b| a + b end
names.each do |name| define_method(name) { send :"do_#{name}" } end
![Page 26: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/26.jpg)
:-(
0k iters/s
1000k iters/s
2000k iters/s
3000k iters/s
4000k iters/s
MRI JRuby
def define_methoddefine_method w/ capture
![Page 27: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/27.jpg)
Optimizing define_method
• Noncapturing
• Treat as method in compiler
• Ignore surrounding scope
• Capturing (future work)
• Lift read-only variables as constant
![Page 28: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/28.jpg)
Getting Better!
0k iters/s
1000k iters/s
2000k iters/s
3000k iters/s
4000k iters/s
MRI JRuby 9.0.1.0 JRuby 9.0.4.0
def define_methoddefine_method w/ capture
![Page 29: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/29.jpg)
Low-cost Exceptions
• Backtrace cost is VERY high on JVM
• Lots of work to construct
• Exceptions frequently ignored
• ...or used as flow control (shame!)
• If ignored, backtrace is not needed!
![Page 30: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/30.jpg)
Postfix Antipattern
foo rescue nil
Exception raisedStandardError rescued
Exception ignored
Result is simple expression, so exception is never visible.
![Page 31: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/31.jpg)
csv.rb Converters
Converters = { integer: lambda { |f| Integer(f) rescue f }, float: lambda { |f| Float(f) rescue f }, ...
All trivial rescues, no traces needed.
![Page 32: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/32.jpg)
Simple rescue Improvement
0
150000
300000
450000
600000
Iters/second
524,475
10,700
![Page 33: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/33.jpg)
Much Better!
1
10
100
1000
10000
100000
1000000
Iters/second
524,475
10,700
![Page 34: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/34.jpg)
Current Work
![Page 35: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/35.jpg)
Inlining
• 900 pound gorilla of optimization
• shove method/closure back to callsite
• eliminate call frames
• eliminate parameter passing/return
![Page 36: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/36.jpg)
But... JVM?
• JVM will inline for us, but...
• only if we use invokedynamic
• and the code isn't too big
• and there's no polymorphic code
• and it feels like it today
![Page 37: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/37.jpg)
Today’s Inliner
def decrement_one(i) i - 1end
i = 1_000_000while i > 0 i = decrement_one(i)end
def decrement_one(i) i - 1end
i = 1_000_000while i < 0 if guard_same? self i = i - 1 else i = decrement_one(i) endend
![Page 38: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/38.jpg)
Today’s Inliner
def decrement_one(i) i - 1end
i = 1_000_000while i > 0 i = decrement_one(i)end
def decrement_one(i) i - 1end
i = 1_000_000while i < 0 if guard_same? self i = i - 1 else i = decrement_one(i) endend
![Page 39: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/39.jpg)
Today’s Inliner
def decrement_one(i) i - 1end
i = 1_000_000while i > 0 i = decrement_one(i)end
def decrement_one(i) i - 1end
i = 1_000_000while i < 0 if guard_same? self i = i - 1 else i = decrement_one(i) endend
![Page 40: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/40.jpg)
Today’s Inliner
def decrement_one(i) i - 1end
i = 1_000_000while i > 0 i = decrement_one(i)end
def decrement_one(i) i - 1end
i = 1_000_000while i < 0 if guard_same? self i = i - 1 else i = decrement_one(i) endend
![Page 41: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/41.jpg)
Inlining Today
• Conceptually simple
• Does not deoptimize
• Works in interpreter and JIT
• Still experimental
• Stack trace reconstitution TBD
![Page 42: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/42.jpg)
Profiling
• You can't inline if you can't profile!
• For each call site record call info
• Which method(s) called
• How frequently
• Inline most frequently-called method
![Page 43: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/43.jpg)
Profiling
0 my_array.each do |object|1 object.execute2 end
code.rb
callsite
![Page 44: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/44.jpg)
Profiling
0 my_array.each do |object|1 object.execute2 end
code.rb class Foo def execute puts "FOO" endend
monomorphic
![Page 45: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/45.jpg)
Profiling
0 my_array.each do |object|1 object.execute2 end
code.rbclass Foo def execute puts "FOO" endend
polymorphic
class Bar def execute puts "BAR" endend
![Page 46: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/46.jpg)
Profiling
• <2% overhead (to be reduced more)
• Working* (interpreter AND JIT)
• Feeds directly into inlining
* Fragile and buggy!
![Page 47: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/47.jpg)
Profilingdef small_loop(i) k = 10 while k > 0 k = yield(k) end i - 1end
def big_loop(i) i = 100_000 while true i = small_loop(i) { |j| j - 1 } return 0 if i < 0 endend
900.times { |i| big_loop i }
hot & monomorphic
Like an Array#each
May see many blocksJVM will not inline this
![Page 48: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/48.jpg)
Inlining FTW!
0
15
30
45
60
Time in seconds
14.1
56.9
![Page 49: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/49.jpg)
Numeric Specialization
• Everything's an object
• JVM has only references and primitives
• Not compatible in bytecode
• Need to optimize numerics as primitive
![Page 50: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/50.jpg)
def looper(n) i = 0 while i < n do_something(i) i += 1 endend
Cached object
Call with iNew Fixnum i + 1
Probably a Fixnum?
![Page 51: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/51.jpg)
def looper(n) i = 0 while i < n do_something(i) i += 1 endend
def looper(long n) long i = 0 while i < n do_something(i) i += 1 endend
Specialize n, i to long
def looper(n) i = 0 while i < n do_something(i) i += 1 endend
Deopt to object version if n or i + 1 is not Fixnum
![Page 52: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/52.jpg)
Interpreter FTW!
• Deopt is much simpler with interpreter
• Collect local vars, instruction index
• Raise exception to bail out
• Fire up interpreter, keep going
• Much cheaper than resuming bytecode
![Page 53: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/53.jpg)
Current Status
• Working prototype
• No deopt
• No type guards
• No overflow check for Fixnum/Bignum
![Page 54: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/54.jpg)
Rendering
* * * * * *** ***** ***** *** * ********* ************* *************** ********************* ********************* ******************* ******************* ******************* ******************* *********************** ******************* ******************* ********************* ******************* ******************* ***************** *************** ************* ********* * *************** *********************** * ************************* * ***************************** * ******************************* * ********************************* *********************************** *************************************** *** ***************************************** *** ************************************************* *********************************************** ********************************************* ********************************************* *********************************************** *********************************************** *************************************************** ************************************************* ************************************************* *************************************************** *************************************************** * *************************************************** * ***** *************************************************** ***** ****** *************************************************** ****** ******* *************************************************** ******* *********************************************************************** ********* *************************************************** ********* ****** *************************************************** ****** ***** *************************************************** ***** *************************************************** *************************************************** *************************************************** *************************************************** ************************************************* ************************************************* *************************************************** *********************************************** *********************************************** ******************************************* ***************************************** ********************************************* **** ****************** ****************** **** *** **************** **************** *** * ************** ************** * *********** *********** ** ***** ***** ** * * * * 0.520000 0.020000 0.540000 ( 0.388744)
![Page 55: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/55.jpg)
def iterate(x,y) cr = y-0.5 ci = x zi = 0.0 zr = 0.0 i = 0 bailout = 16.0 max_iterations = 1000 while true i += 1 temp = zr * zi zr2 = zr * zr zi2 = zi * zi zr = zr2 - zi2 + cr zi = temp + temp + ci return i if (zi2 + zr2 > bailout) return 0 if (i > max_iterations) endend
![Page 56: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/56.jpg)
Mandelbrot performance
0
0.35
0.7
1.05
1.4
JRuby JRuby + unbox JRuby + truffle
![Page 57: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/57.jpg)
Mandelbrot performance
0
0.04
0.08
0.12
0.16
JRuby JRuby + unbox JRuby + truffle
![Page 58: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/58.jpg)
When?
• Profiling, inlining mostly need testing
• Specialization needs guards, deopt
• Probably landing in next couple months
![Page 59: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/59.jpg)
JRuby 9.1.0.0
• Coming soon (end of Feb?)
• Ruby 2.3 support
• Some of these optimizations
• More attention to performance overall
![Page 60: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/60.jpg)
![Page 61: FOSDEM 2016 - JRuby 9000 · JRuby 9000 Optimizing Above the JVM. Me • Charles Oliver Nutter • @headius • Red Hat • Based in Minneapolis, Minnesota • Ten years working on](https://reader031.vdocument.in/reader031/viewer/2022013022/5f4b6f3d3e72df213919d0c8/html5/thumbnails/61.jpg)