7 ms·
I'm pretty sure (there isn't a lot of info on how to enable it in production workloads) we're running YJIT in production and didn't notice any improvement in lo
by erikrothoff 4y ago
I'm pretty sure (there isn't a lot of info on how to enable it in production workloads) we're running YJIT in production and didn't notice any improvement in load times, CPU usage or anything really. If any slightly higher metrics across the board.
We're using Rails as API and web frontend with a pretty high number of requests per second, so I was hoping we'd see something. Does anyone have any experience rolling it out?
- jrochkind1 4y ago> I'm pretty sure (there isn't a lot of info on how to enable it in production workloads The YJIT is not on by default in ruby 3.2, you have to specifically enable it. If you aren't sure if you have enabled it... what makes you pretty sure you have enabled it? It seems possible you have not enabled it, if you aren't confident you know how to do so? I am not using it yet myself, and don't want to put any possibly incorrect info here about how to enable it. I agree that it's not clear to me where to find this documented. I am pretty sure it is not on by default.
- erikrothoff 4y agoYes, I'm pretty sure because: 1. Compiled with jyjit confrmed (ruby --yjit) returns the correct value 2. RubyVM::YJIT.enabled? returned true I didn't notice any improvements at basically so I can't really say _for sure_ if it was working as intended.
- jrochkind1 4y agoRubyVM::YJIT.enabled? returning true does seem to settle it, and no need to say "pretty sure" with qualifications!
- JohnBooty 4y agoThe gist of it is that you need to build Ruby with `RUBY_CONFIGURE_OPTS=--enable-yjit` true and verify it is enabled with `ruby --enable-yjit --version` and then finally run your code with `ruby --enable-yjit foo.rb`. For Rails you'd want to just edit the executable Rails scripts like `bin/rails` to include that flag.
- MSkog 4y agoYou can also set RUBY_YJIT_ENABLE=1 to enable it.
- erikrothoff 4y agoThat’s what I ended up using: passenger_env_var RUBY_YJIT_ENABLE 1;
- jrochkind1 4y agoThanks! Is there a "canonical" place to find this documented, like with the ruby distro? > For Rails you'd want to just edit the executable Rails scripts like `bin/rails` to include that flag. Alternately, you can edit your shell init scripts to put the correct thing in `RUBY_OPTS` ENV variable, yes? I would consider this preferable to editing executable rails scripts with implementation-specific stuff (and then hoping that the app is always launched with those edited shell scripts, which I'm not sure eg `bundle exec rails` will do). I don't think editing Rails scripts is probably the "right" or recommended way to do this. But I'm not going to try to specify what you put in `RUBY_OPTS` since i haven't done it myself and don't want to spread misinformation! (Again, is this documented in a centralized trustworthy place? As I try to google it... I am somewhat frustrated with the ruby documentation situation!)
- MSkog 4y agoPerhaps this is what you are looking for: https://github.com/ruby/ruby/blob/master/doc/yjit/yjit.md https://github.com/ruby/ruby/blob/master/doc/yjit/yjit.md
- jrochkind1 4y agothank you!
- jwcooper 4y agoWe're using puma and set the RUBYOPT=--yjit in a systemd environment variable for our puma service. The performance impact of enabling yjit was quite obvious in our charts. Another giveaway that it's properly enabled is the servers will use consume more memory.
- simantel 4y agoAlso worth noting that the Ruby 3.2 Docker image can't run with YJIT yet, so if your production setup is in a container, it's most likely not using YJIT. GitHub issue link here: https://github.com/docker-library/ruby/pull/398 https://github.com/docker-library/ruby/pull/398
- ufuk 4y agoThat's not correct: $ podman run -it -e RUBYOPT="--yjit" ruby:3.2 irb(main):001:0> puts RUBY_DESCRIPTION ruby 3.2.0 (2022-12-25 revision a528908271) +YJIT [aarch64-linux] => nil
- nickjj 4y agoIt was supported immediately for Alpine based images because rustc 1.60+ was available in that distro. Initially when 3.2 was released Debian based images didn't support it because Bullseye ships with a version of rustc that's too old to compile YJIT. But https://github.com/docker-library/ruby/commit/6db728e https://github.com/docker-library/ruby/commit/6db728e addressed this a few days ago by installing a pre-compiled version of rustc straight from Rust and YJIT is available in Debian now. You can confirm if it's available to use by running: $ docker container run --rm ruby:3.2.0-slim-bullseye ruby --enable-yjit -v ruby 3.2.0 (2022-12-25 revision a528908271) +YJIT [x86_64-linux] If it weren't available then you would get an unknown argument error.
- sitkack 4y ago$ docker container run --rm ruby:3.2.0-slim-bullseye ruby --enable-yjit -v ruby 3.2.0 (2022-12-25 revision a528908271) +YJIT [aarch64-linux] Runs on Arm as well!
- JohnBooty 4y agoDoes anyone have any experience rolling it out? FWIW, the linked article has prod benchmarks. I'm pretty sure (there isn't a lot of info on how to enable it in production workloads) we're running YJIT in production Sure you're running it? You have to compile with YJIT support, and then pass the command line arg. (It doesn't support YJIT out of the box because, I presume, they didn't want to force a Rust dependency on everybody?) Here's how on MacOS + asdf, others will be similar. Note that I think --enable-yjit might work (but do nothing) even if you don't have support compiled in. # if you already installed 3.2.0 asdf uninstall ruby 3.2.0 # install Rust asdf plugin-add rust asdf... # now install Ruby 3.2 asdf plugin-update ruby export RUBY_CONFIGURE_OPTS=--enable-yjit asdf install ruby 3.2.0 asdf global ruby 3.2.0 # verify it's installed and ready ruby --enable-yjit --version # now run your workload ruby --enable-yjit foo.rb
- erikrothoff 4y agoYes, I'm pretty sure because: 1. Compiled with jyjit confrmed (ruby --yjit) returns the correct value 2. RubyVM::YJIT.enabled? returned true But the information available on how to confirm YJIT is running is not super clear. Since I didn't notice any improvements I started wondering.
- JohnBooty 4y agoSounds like you're running it! Since I didn't notice any improvements I started wondering. It only speeds up Ruby itself. In a "real world" web app performance, performance is mostly dominated by Ruby/PHP/Java/whatever sitting around and waiting for database queries to execute. So for a lot of web workloads the perf increase won't be huge. If your average endpoint is e.g. 5ms of Ruby and 500ms of DB queries, your max speedup will be negligible if you switch to YJIT... or even if you rewrite the whole app in hand-optimized assembler. (Also gets to the root of why perf-based criticism of Ruby is usually dumb, IMHO. It's usually not the problem)
- why-el 4y agoThe top comment in HN is one where the poster is not 100% is using the thing we are discussing.
- byroot 4y agoThere might be a number of reasons why YJIT isn't effective in your application. The best way to know it to enable YJIT runtime statistics [0] to see whether YJIT is doing a lot of side exits and if so why. But it requires a bit of YJIT knowledge to interpret them. It's also entirely possible that your application isn't CPU bound in the first place, or that it's bottlenecked by things YJIT can't do anything about (e.g. GVL). That's close to impossible to guess what it might be without being able to instrument the application. [0] https://github.com/ruby/ruby/blob/df6b72b8ff7af16a56fa48f3b4abb1d8850f4d1c/doc/yjit/yjit.md#performance-tips https://github.com/ruby/ruby/blob/df6b72b8ff7af16a56fa48f3b4...