diff options
author | Noah Gibbs <noah.gibbs@shopify.com> | 2022-01-11 19:17:59 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-11 14:17:59 -0500 |
commit | 14967347b9bb819c365c73dd035baac723d56b51 (patch) | |
tree | 5d4aa458b8051ebc91fea50f794e27c09e771f44 /doc/yjit | |
parent | 34ebf82e839bf542444a92e075853ff8f6332156 (diff) | |
download | ruby-14967347b9bb819c365c73dd035baac723d56b51.tar.gz |
YJIT stats documentation additions and updates (#5427)
* YJIT documentation additions and updates
* Update yjit.md
Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
Diffstat (limited to 'doc/yjit')
-rw-r--r-- | doc/yjit/yjit.md | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/doc/yjit/yjit.md b/doc/yjit/yjit.md index a56aec652a..a7ad205f5c 100644 --- a/doc/yjit/yjit.md +++ b/doc/yjit/yjit.md @@ -68,7 +68,7 @@ git clone https://github.com/Shopify/yjit 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 - `--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 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. |