summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoah Gibbs <noah.gibbs@shopify.com>2022-01-11 19:17:59 +0000
committerGitHub <noreply@github.com>2022-01-11 14:17:59 -0500
commit14967347b9bb819c365c73dd035baac723d56b51 (patch)
tree5d4aa458b8051ebc91fea50f794e27c09e771f44
parent34ebf82e839bf542444a92e075853ff8f6332156 (diff)
YJIT stats documentation additions and updates (#5427)
* YJIT documentation additions and updates * Update yjit.md Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
Notes
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
-rw-r--r--doc/yjit/yjit.md46
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 &mdash; 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.