ruby-changes:70824
From: Noah <ko1@a...>
Date: Wed, 12 Jan 2022 04:18:15 +0900 (JST)
Subject: [ruby-changes:70824] 14967347b9 (master): YJIT stats documentation additions and updates (#5427)
https://git.ruby-lang.org/ruby.git/commit/?id=14967347b9 From 14967347b9bb819c365c73dd035baac723d56b51 Mon Sep 17 00:00:00 2001 From: Noah Gibbs <noah.gibbs@s...> Date: Tue, 11 Jan 2022 19:17:59 +0000 Subject: YJIT stats documentation additions and updates (#5427) * YJIT documentation additions and updates * Update yjit.md Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@g...> --- doc/yjit/yjit.md | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/doc/yjit/yjit.md b/doc/yjit/yjit.md index a56aec652ad..a7ad205f5cd 100644 --- a/doc/yjit/yjit.md +++ b/doc/yjit/yjit.md @@ -68,7 +68,7 @@ git clone https://github.com/Shopify/yjit https://github.com/ruby/ruby/blob/trunk/doc/yjit/yjit.md#L68 cd yjit ``` -The YJIT `ruby` binary can be built with either GCC or Clang. For development, we recommend enabling debug symbols so that assertions are enabled as this makes debugging easier. Enabling debug mode will also make it possible for you to disassemble code generated by YJIT. However, this causes a performance hit. For maximum performance, compile with GCC, without the `DRUBY_DEBUG` or `YJIT_STATS` build options. More detailed build instructions are provided in the [Ruby README](https://github.com/ruby/ruby#how-to-compile-and-install). +The YJIT `ruby` binary can be built with either GCC or Clang. For development, we recommend enabling debug symbols so that assertions are enabled as this makes debugging easier. Enabling debug mode will also make it possible for you to disassemble code generated by YJIT. However, this causes a performance hit. For maximum performance, compile with GCC, without the `-DRUBY_DEBUG` or `-DYJIT_STATS` build options. More detailed build instructions are provided in the [Ruby README](https://github.com/ruby/ruby#how-to-compile-and-install). To support disassembly of the generated code, `libcapstone` is also required (`brew install capstone` on MacOS, `sudo apt-get install -y libcapstone-dev` on Ubuntu/Debian and `sudo dnf -y install capstone-devel` on Fedora). ``` @@ -130,7 +130,7 @@ YJIT supports all command-line options supported by upstream CRuby, but also add https://github.com/ruby/ruby/blob/trunk/doc/yjit/yjit.md#L130 - `--disable-yjit`: turn off YJIT (enabled by default) - `--yjit-stats`: produce statistics after the execution of a program (must compile with `cppflags=-DRUBY_DEBUG` to use this) -- `--yjit-exec-mem-size=N`: size of the executable memory block to allocate (default 256 MiB) +- `--yjit-exec-mem-size=N`: size of the executable memory block to allocate, in MiB (default 256 MiB) - `--yjit-call-threshold=N`: number of calls after which YJIT begins to compile a function (default 2) - `--yjit-max-versions=N`: maximum number of versions to generate per basic block (default 4) - `--yjit-greedy-versioning`: greedy versioning mode (disabled by default, may increase code size) @@ -156,6 +156,48 @@ This section contains tips on writing Ruby code that will run as fast as possibl https://github.com/ruby/ruby/blob/trunk/doc/yjit/yjit.md#L156 You can also compile YJIT in debug mode and use the `--yjit-stats` command-line option to see which bytecodes cause YJIT to exit, and refactor your code to avoid using these instructions in the hottest methods of your code. +### Memory Statistics + +YJIT, including in production configuration, keeps track of the size of generated code. If you check YJIT.runtime_stats you can see them: + +``` +$ RUBYOPT="--yjit" irb +irb(main):001:0> RubyVM::YJIT.runtime_stats +=> {:inline_code_size=>331945, :outlined_code_size=>272980} +``` + +These are the size in bytes of generated inlined code and generated outlined code. If the combined sizes for generated code are very close to the total YJIT exec-mem-size (see above), YJIT will stop generating code once the limit is reached. Try to make sure you have enough exec-mem-size for the program you're running. By default YJIT will allocate 268,435,456 bytes (256 MiB) of space for generated inlined and outlined code. + +### Other Statistics + +If you compile Ruby with RUBY_DEBUG and/or YJIT_STATS defined and run with "--yjit --yjit-stats", YJIT will track and return performance statistics in RubyVM::YJIT.runtime_stats. + +``` +$ RUBYOPT="--yjit --yjit-stats" irb +irb(main):001:0> YJIT.runtime_stats +=> +{:inline_code_size=>340745, + :outlined_code_size=>297664, + :all_stats=>true, + :exec_instruction=>1547816, + :send_callsite_not_simple=>7267, + :send_kw_splat=>7, + :send_ivar_set_method=>72, +... +``` + +Some of the counters include: + +:exec_instruction - how many Ruby bytecode instructions have been executed +:binding_allocations - number of bindings allocated +:binding_set - number of variables set via a binding +:vm_insns_count - number of instructions executed by the Ruby interpreter +:compiled_iseq_count - number of bytecode sequences compiled + +Counters starting with "exit_" show reasons for YJIT code taking a side exit (return to the interpreter.) See yjit_hacking.md for more details. + +Performance counter names are not guaranteed to remain the same between Ruby versions. If you're curious what one does, it's usually best to search the source code for it — but it may change in a later Ruby version. + ## Contributing We welcome open source contributors. You should feel free to open new issues to report bugs or just to ask questions. -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/