4

Merge YJIT: an in-process JIT compiler by maximecb · Pull Request #4992 · ruby/r...

 2 years ago
source link: https://github.com/ruby/ruby/pull/4992
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Copy link

Contributor

maximecb commented 2 days ago

edited

This PR introduces YJIT, a just-in-time compiler built using a Lazy Basic Block Versioning (LBBV) compiler architecture. For more details about the technique, please refer to Maxime’s published paper and recorded talks:

YJIT currently provides average speedups of 23% over the CRuby interpreter on realistic benchmarks, and near-instant warm-up time. Plans are to include YJIT in the Ruby 3.1 preview release so that more users can test it out and benefit from potential performance gains.

Current limitations:

  • Disabled by default, must specify --yjit to enable or set YJIT_RUBY_ENABLE=1
  • Currently supports only macOS and Linux.
  • Currently supports only x86-64 CPUs.
  • On unsupported platforms, Ruby runs with the interpreter just like before
  • No garbage collection for generated code. Will produce an error if --yjit-exec-mem-size is exceeded. This should be fixed in the coming months.
  • YJIT uses more memory when active because it needs to allocate machine code. This can be adjusted by setting --yjit-exec-mem-size.

YJIT integrates closely with the interpreter and some core runtime routines such as rb_obj_is_kind_of() and rb_str_eql_internal(). YJIT also introduces a number of callbacks (see yjit.h) so that it can be notified of certain events, such as constants or methods being redefined. These changes are necessary so that YJIT can deoptimize code. These callbacks could potentially be useful for MJIT as well.

YJIT does not spawn an external compiler as a sub-process for compilation. YJIT compiles concurrently with Ruby code execution on the same thread. Despite this, it provides near-instant warm-up. That is, YJIT typically delivers a speedup on the first iteration of our benchmarks.

Shopify is committed to making sure that YJIT remains in good working order. This PR adds new test workflows to help detect issues early on. Should bugs and issues arise, we will assist in investigating and fixing these in a timely manner. If necessary, code generation for specific YARV instructions can be disabled by commenting a single line near the end of yjit_codegen.c.

We have tried to keep the YJIT code clean and approachable. The codebase is well-commented. We have a number of non-Shopify contributors who have found YJIT and submitted code.

YJIT makes additional runtime checks if compiled with RUBY_DEBUG > 0. It can also collect runtime statistics if compiled with RUBY_DEBUG or YJIT_STATS > 0 and also run with the --yjit-stats option or the RUBY_YJIT_STATS environment variable set to 1.

YJIT cannot be enabled at the same time as MJIT. Both can be compiled into Ruby, but only one can be active at runtime.

Contributors to the YJIT project so far:
Alan Wu
Aaron Patterson
Benson Muite
Dylan Smith
Eileen Uchitelle
Max Bernstein
Marc Feeley
Jose Narvaez
Jean Boussier
John Hawthorn
Kevin Newton
Maxime Chevalier-Boisvert
Mike Dalessio
Noah Gibbs
Takashi Kokubun
Ufuk Kayserilioglu


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK