https://github.com/ruby/ruby/pull/7448

Skip to content Toggle navigation
 
Sign up

  * Product
      +  
        Actions
        Automate any workflow
      +  
        Packages
        Host and manage packages
      +  
        Security
        Find and fix vulnerabilities
      +  
        Codespaces
        Instant dev environments
      +  
        Copilot
        Write better code with AI
      +  
        Code review
        Manage code changes
      +  
        Issues
        Plan and track work
      +  
        Discussions
        Collaborate outside of code
      + Explore
      + All features
      + Documentation
      + GitHub Skills
      + Blog
  * Solutions
      + For
      + Enterprise
      + Teams
      + Startups
      + Education
      + By Solution
      + CI/CD & Automation
      + DevOps
      + DevSecOps
      + Case Studies
      + Customer Stories
      + Resources
  * Open Source
      +  
        GitHub Sponsors
        Fund open source developers
      +  
        The ReadME Project
        GitHub community articles
      + Repositories
      + Topics
      + Trending
      + Collections
  * Pricing

[                    ] 

  *  
    #
    In this repository All GitHub |
    Jump to |

  * No suggested jump to results

  *  
    #
    In this repository All GitHub |
    Jump to |
  *  
    #
    In this organization All GitHub |
    Jump to |
  *  
    #
    In this repository All GitHub |
    Jump to |

Sign in
Sign up
{{ message }}
ruby / ruby Public

  * Notifications
  * Fork 5.3k
  * Star 20k

  * Code
  * Pull requests 400
  * Actions
  * Security
  * Insights

More

  * Code
  * Pull requests
  * Actions
  * Security
  * Insights

New issue

Have a question about this project? Sign up for a free GitHub account
to open an issue and contact its maintainers and the community.

Pick a username
    [                    ]

Email Address
    [                    ]

Password
    [                    ]

[                    ] Sign up for GitHub
By clicking "Sign up for GitHub", you agree to our terms of service
and privacy statement. We'll occasionally send you account related
emails.

Already on GitHub? Sign in to your account

Jump to bottom

RJIT #7448

Merged
k0kubun merged 98 commits into ruby:master from k0kubun:rjit Mar 6,
2023
Merged

RJIT #7448

k0kubun merged 98 commits into ruby:master from k0kubun:rjit Mar 6,
2023
+4,611 -642 
Conversation 6 Commits 98 Checks 95 Files changed 25

Conversation

This file contains bidirectional Unicode text that may be interpreted
or compiled differently than what appears below. To review, open the
file in an editor that reveals hidden Unicode characters. Learn more
about bidirectional Unicode characters
Show hidden characters
k0kubun
Copy link
Member

@k0kubun k0kubun commented Mar 5, 2023 *
edited

full diff^1: 55367b3...22d944c

Description

This PR replaces the current implementation of MJIT with a new JIT
called "RJIT" ^2.

  * RJIT uses a pure-Ruby assembler to generate native code
      + MJIT requires a C compiler at runtime. YJIT requires a Rust
        compiler at build time. RJIT doesn't require them.
      + This means that RJIT's warmup could be slower than YJIT, but
        it's still much faster than MJIT's.
  * The code generated by RJIT looks very similar to YJIT
      + In fact, many methods are direct translations of the Rust
        code into Ruby.
      + This allows us to simplify the Ruby VM by removing
        MJIT-specific implementations.
      + We could do some early experiments for YJIT in RJIT too if we
        want.

See the ticket for motivation and further details: [Feature #19420]

Benchmark

I benchmarked the interpreter, YJIT, RJIT, and MJIT with yjit-bench.

Headline

RJIT's performance is still nowhere near YJIT's, but notably RJIT
outperforms MJIT in all headline benchmarks, which are considered the
most real-world workloads. RJIT gives a small speedup on railsbench
even with yjit-bench's short warmup.

output_543

Other

Sometimes MJIT is still better than RJIT. However, RJIT outperforms
both YJIT and MJIT on Optcarrot, which was the benchmark used for the
Ruby 3x3 milestone.

output_542

Micro

30k_ifelse and 30k_methods are the things that YJIT is very good at,
but RJIT outperforms YJIT on them. This seems to be because YJIT
chose to interleave inline code and outlined code for Code GC and
arm64's performance whereas RJIT doesn't do that. This is a good
reminder of the code layout's impact.

output_544

Footnotes

 1. I merged this branch in multiple batches because pushing hundreds
    of commits at once pressures our notification system a bit.
    However, an auto-format commit interrupted the operation, so I
    needed to resolve the conflict and this PR has only the diff
    after that commit. -

 2. This PR doesn't rename the interface and internal names from MJIT
    to RJIT yet, but a separate PR will do that soon. -

Sorry, something went wrong.

 37 toshimaru, claudiug, scaint, hss-mateus, koic, jhawthorn,
tenderlove, sarna, rainerborene, evanwalsh, and 27 more reacted with
hooray emoji [?] 17 tenderlove, sarna, rainerborene, wildmaples,
mohits, dreig, shanempope, basex, dalpo, sadiqmmm, and 7 more reacted
with heart emoji  3 krmbzds, ethransom, and thdaraujo reacted with
rocket emoji  2 evanwalsh and thdaraujo reacted with eyes emoji
All reactions

  *  37 reactions
  * [?] 17 reactions
  *  3 reactions
  *  2 reactions

@k0kubun k0kubun force-pushed the rjit branch 6 times, most recently
from e37b624 to bac3243 Compare March 6, 2023 06:47
@k0kubun k0kubun marked this pull request as ready for review March
6, 2023 07:21
k0kubun added 23 commits March 5, 2023 23:26
@k0kubun
Implement variadic C func calls
6055b8d
@k0kubun
Fix a typo in jit_chain_guard
8d4636c
@k0kubun
Side-exit earlier on interrupts
5c8303e
@k0kubun
Implement branchif
084121a
@k0kubun
Implement opt_le, opt_ge, and opt_gt
1df6ec3
@k0kubun
Implement Array#[]
59e307b
@k0kubun
Implement opt_mod
9695dbf
@k0kubun
Implement setlocal_WC_0
c7e3c46
@k0kubun
Implement opt_and and opt_or
3027b1f
@k0kubun
Format numbers with delimiters
e3e9b11
@k0kubun
Implement opt_eq and opt_neq
d71aa17
@k0kubun
Implement all getlocal/setlocal insns
d3fe61c
@k0kubun
Implement dupn and setn
4139fd9
@k0kubun
Initial support of opt_getconstant_path
96d77d9
@k0kubun
Side-exit on cfunc with -2 argc
54b28c8
@k0kubun
Count opt_getconstant_path exit reasons
76040da
@k0kubun
Implement duparray and expandarray
e88e503
@k0kubun
Implement opt_aset
13efcbd
@k0kubun
Count optimized method types
c6c1787
@k0kubun
Implement opt_invokebuiltin_delegate
f232482
@k0kubun
Remove unneeded ci references
b4a9370
@k0kubun
Implement optimized send
51de863
@k0kubun
Invalidate blocks on constant IC updates
d1f0a38
41 hidden items Load more...
k0kubun added 21 commits March 5, 2023 23:27
@k0kubun
Chain-guard blockarg
ae64db3
@k0kubun
Implement optimized call
ced8768
@k0kubun
Reset chain_depth in more places
96746f3
@k0kubun
Implement alias
124f96f
@k0kubun
Implement bmethod
7e60000
@k0kubun
Implement struct aref
73f9b91
@k0kubun
Optimize Module#===
10dbb40
@k0kubun
Optimize String#getbyte
836d91b
@k0kubun
Remove an obsoleted test
8274778
@k0kubun
Remove duplicated declarations
1dcb48d
@k0kubun
Update dependencies
e3b0229
@k0kubun
Rely on YJIT's switch for now
cf79ce3
@k0kubun
Resurrect CI for MJIT
89ce388
@k0kubun
Remove unused variables
828f7a7
@k0kubun
Workaround USE_MJIT warnings
cc8a2ba
@k0kubun
Change default call threshold to 30
12a4077
@k0kubun
Omit test_version for Cirrus for now
41c22d1
@k0kubun
Add Mod 10 to cmp r/m64, imm8
05df180
@k0kubun
Add Mod 10 to test r/m64, imm32
b7f13f7
@k0kubun
Fix a BytePtr check of test
8985dc6
@k0kubun
Avoid crashing at a random ISEQ access ...
dbd34e1

[Feature #19420]

@k0kubun k0kubun force-pushed the rjit branch from 036f94b to dbd34e1
Compare March 6, 2023 07:28
Hide details View details @k0kubun k0kubun merged commit 22d944c into
ruby:master Mar 6, 2023
3 of 8 checks passed
@k0kubun k0kubun deleted the rjit branch March 6, 2023 07:29
@eregon
Copy link
Member

eregon commented Mar 6, 2023 *
edited

Nice! Finally a JIT in a nice language^^
Chris Seaton was always saying we should write a Ruby JIT in Ruby,
and for sure it feels elegant.

Do you have a link to the full list of commits/diff? -> it's already
in the description :)

    I merged this branch in multiple batches because pushing hundreds
    of commits at once pressures our notification system a bit

Could we just merge them at once (in the future) and let the
notification system deal with it at its own pace?
Does the notification system need to notify for every commit?
Notifying once per push would probably solve that.

Regarding the Headline benchmarks, would you also have numbers with
enough warmup for MJIT? Otherwise it's just showing MJIT takes longer
to warmup but not comparing peak performance/how much it can
optimize.

All reactions

Sorry, something went wrong.

@k0kubun
Copy link
Member Author

k0kubun commented Mar 6, 2023 *
edited

    Notifying once per push would probably solve that.

Yeah, definitely. I may try that path next time.

    Regarding the Headline benchmarks, would you also have numbers
    with enough warmup for MJIT?

I used your warmup harness and this was the medians that it printed (
full details):

    bench     interp (ms) yjit (ms) rjit (ms) mjit (ms)
activerecord  111         67        94        112
hexapdf       1807        1173      1593      1777
liquid-c      44          31        38        44
liquid-render 110         62        83        91
mail          94          72        88        97
psych-load    1432        986       1174      1202
railsbench    1497        980       1340      1584
ruby-lsp      45          33        40        95
sequel        89          79        103       194

Also this was the last time I seriously benchmarked MJIT with enough
warmup. At least on railsbench, I've only seen 1.02~1.05x speedup
with MJIT at best, so RJIT will most likely be faster than MJIT
regardless.

All reactions

Sorry, something went wrong.

@tenderlove
Copy link
Member

tenderlove commented Mar 6, 2023

Now I need to make TenderJIT outperform RJIT 

 39 sorah, adam12, DRBragg, D-system, 007lva, jcmfernandes, sci-phi,
wildmaples, alexandremcosta, carlomunguia, and 29 more reacted with
laugh emoji
All reactions

  *  39 reactions

Sorry, something went wrong.

@k0kubun
Copy link
Member Author

k0kubun commented Mar 6, 2023

Good news is that you've got a lot of new RubyVM::MJIT::C APIs (which
will be RubyVM::RJIT::C soon) for making that happen 

All reactions

Sorry, something went wrong.

@jensengrey
Copy link

jensengrey commented Mar 8, 2023

This is amazing. Wonderful work.

The benchmark times include JIT overhead correct? Is there a graph of
just the JIT overhead. What Ruby methods does RJIT rely heavily on
and could they be sped up by RJIT? How does one use RJIT to make RJIT
itself faster (lower latency).

All reactions

Sorry, something went wrong.

@k0kubun
Copy link
Member Author

k0kubun commented Mar 8, 2023

Full details are in https://gist.github.com/k0kubun/
4e31fd289f8e3543dc094421eca90861. I haven't implemented a feature to
render a graph to visualize the warmup performance, but you can see
how it behaves on the 1st iteration, etc.

 3 jensengrey, ignoramous, and jph reacted with eyes emoji
All reactions

  *  3 reactions

Sorry, something went wrong.

Sign up for free to join this conversation on GitHub. Already have an
account? Sign in to comment
Reviewers
No reviews
Assignees
No one assigned
Labels
None yet
Milestone
No milestone
4 participants
@k0kubun @eregon @tenderlove @jensengrey
Add this suggestion to a batch that can be applied as a single
commit. This suggestion is invalid because no changes were made to
the code. Suggestions cannot be applied while the pull request is
closed. Suggestions cannot be applied while viewing a subset of
changes. Only one suggestion per line can be applied in a batch. Add
this suggestion to a batch that can be applied as a single commit. 
Applying suggestions on deleted lines is not supported. You must
change the existing code in this line in order to create a valid
suggestion. Outdated suggestions cannot be applied. This suggestion
has been applied or marked resolved. Suggestions cannot be applied
from pending reviews. Suggestions cannot be applied on multi-line
comments. Suggestions cannot be applied while the pull request is
queued to merge.

Footer

 (c) 2023 GitHub, Inc.

Footer navigation

  * Terms
  * Privacy
  * Security
  * Status
  * Docs
  * Contact GitHub
  * Pricing
  * API
  * Training
  * Blog
  * About

You can't perform that action at this time.
You signed in with another tab or window. Reload to refresh your
session. You signed out in another tab or window. Reload to refresh
your session.