Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ruby 2.6 JIT / RubyConf 2018

Ruby 2.6 JIT / RubyConf 2018

RubyConf 2018 Los Angeles

Takashi Kokubun

November 15, 2018
Tweet

More Decks by Takashi Kokubun

Other Decks in Programming

Transcript

  1. def plus(a, b) a + b end + a b

    Parse Ruby 1.8 Traverse
  2. def plus(a, b) a + b end + a b

    Compile Ruby 1.9~2.5 Interpret getlocal :a getlocal :b send :+
  3. def plus(a, b) a + b end + a b

    JIT Ruby 2.6 (New!) Execute getlocal :a getlocal :b send :+ mov %rdi,%rdx mov %rsi,%rax add %rdx,%rax
  4. unused space code readonly data unused space code readonly data

    unused space code readonly data 3 methods Heap
  5. unused space code readonly data unused space code readonly data

    unused space code readonly data L2, ... cache L1 cache Heap
  6. unused space code readonly data unused space code readonly data

    unused space code readonly data L2, ... cache L1 cache Heap
  7. unused space Heap code readonly data unused space code readonly

    data unused space code readonly data L2, ... cache L1 cache
  8. unused space code readonly data unused space code readonly data

    unused space code readonly data When it reaches --jit-max-cache, it fires "JIT compaction"
  9. unused space code readonly data unused space code readonly data

    unused space code readonly data unused space code code code readonly data readonly data readonly data
  10. unused space code readonly data unused space code readonly data

    unused space code readonly data unused space code code code readonly data readonly data readonly data L2, ... cache
  11. What's TracePoint? When is it enabled? • gem 'web-console' on

    your Rails application • byebug or binding.pry (with pry-byebug) • Measuring coverage
  12. Summary: When JIT makes Ruby slow Optcarrot Rails 1. When

    there are many JIT-ed methods ✓ 2. When there are still methods to be JIT-ed (Is it a short benchmark?) ✓ 3. When TracePoint is enabled
  13. def plus(a, b) a + b end Virtual Machine getlocal

    :a getlocal :b send :+ Program Counter Stack Pointer Computer Registers Instruction Pointer
  14. def plus(a, b) a + b end Virtual Machine getlocal

    :a getlocal :b send :+ Program Counter Stack Pointer Computer JIT Instruction Pointer Registers mov %rdi,%rdx mov %rsi,%rax add %rdx,%rax
  15. VM-optimized methods Integer, Float +, -, *, /, % Array

    +, <<, [], []=, empty?, size, length, min, max Hash [], []=, empty?, size, length String +, <<, =~, empty?, size, length, succ common !, !=, ==, <, >, <=, >=
  16. def three 1 + 2 end putobject 1 putobject 2

    send :+ JIT mov $0x3,%eax retq Method inlining on JIT
  17. Method dispatch on Ruby VM foo.bar Method search (slow) Ruby

    method C function attr_reader alias Method entry Foo#bar
  18. Method dispatch on Ruby VM foo.bar Method search (slow) Verify

    cache Ruby method C function attr_reader alias Method entry Foo#bar has cache
  19. Method dispatch on Ruby VM foo.bar Method search (slow) Verify

    cache Ruby method C function attr_reader alias Method entry Foo#bar has cache redefined?
  20. Method dispatch on Ruby VM foo.bar Method search (slow) Verify

    cache Ruby method C function attr_reader alias Method entry Foo#bar has cache redefined?
  21. Method dispatch on JIT foo.bar Verify cache Ruby method Method

    entry Foo#bar has cache Cancel JIT! Less branches Less memory access redefined? some inlining
  22. Reading instance variable on VM @foo Search index (many branches,

    slow) self.class. instance_variables[index = 2]
  23. Reading instance variable on VM Search index (many branches, slow)

    self.class. instance_variables[index = 2] @foo has cache Verify cache
  24. Reading instance variable on VM Search index (many branches, slow)

    self.class. instance_variables[index = 2] @foo different class? has cache Verify cache
  25. Reading instance variable on VM Search index (many branches, slow)

    self.class. instance_variables[index = 2] @foo different class? has cache Verify cache
  26. Reading instance variable on JIT self.class. instance_variables[2] @foo different class?

    has cache Verify cache Cancel JIT! inlined index Less branches Less memory access
  27. Summary: When JIT makes Ruby fast Optcarrot Rails 1. Almost

    all methods ✓ ✓ 2. Basic operators on core classes ✓ 3. Calling Ruby method ✓ ✓ 4. Instance variable access ✓ ?
  28. Future idea (not for 2.6) • Stack allocation of objects

    - That requires "escape analysis" (not easy) - We haven't estimated its possible impact yet
  29. Some rooms for improvements in 2.6 (!?) • Change heuristics

    to trigger/compact JIT • Profile-guided optimization • Method inlining
  30. Conclusion • Ruby 2.6.0-preview3 JIT is still early days -

    Small --jit-max-cache might be an option for now • We still have chance to make Ruby 2.6.0 better - Benchmarks are wanted!!!