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.