diff options
author | Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> | 2023-11-03 17:07:13 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-03 21:07:13 +0000 |
commit | 6e38076b1689af98ab1164af9119b9304e54829a (patch) | |
tree | e043396c843dce64271d31975bcc667f4a2890e9 /yjit | |
parent | 38bdb9d0da1647a9b91463183a9b61330243d908 (diff) |
YJIT: implement two-step call threshold (#8839)
* YJIT: implement two-step call threshold
Automatically switch call threshold to a larger value for
larger, production-sized apps, while still allowing smaller apps
and command-line programs to start with a lower threshold.
* Update yjit/src/options.rs
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
* Make the new variables constants
* Check that a custom call threshold was not specified
---------
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
Diffstat (limited to 'yjit')
-rw-r--r-- | yjit/src/options.rs | 15 | ||||
-rw-r--r-- | yjit/src/yjit.rs | 8 |
2 files changed, 20 insertions, 3 deletions
diff --git a/yjit/src/options.rs b/yjit/src/options.rs index fe0a7ec9cc..98c0548677 100644 --- a/yjit/src/options.rs +++ b/yjit/src/options.rs @@ -2,17 +2,26 @@ use std::{ffi::{CStr, CString}, ptr::null}; use crate::backend::current::TEMP_REGS; use std::os::raw::{c_char, c_int, c_uint}; +// Call threshold for small deployments and command-line apps +pub static SMALL_CALL_THRESHOLD: u64 = 30; + +// Call threshold for larger deployments and production-sized applications +pub static LARGE_CALL_THRESHOLD: u64 = 120; + +// Number of live ISEQs after which we consider an app to be large +pub static LARGE_ISEQ_COUNT: u64 = 40_000; + // This option is exposed to the C side a a global variable for performance, see vm.c // Number of method calls after which to start generating code // Threshold==1 means compile on first execution #[no_mangle] -static mut rb_yjit_call_threshold: u64 = 30; +pub static mut rb_yjit_call_threshold: u64 = SMALL_CALL_THRESHOLD; // This option is exposed to the C side a a global variable for performance, see vm.c // Number of execution requests after which a method is no longer // considered hot. Raising this results in more generated code. #[no_mangle] -static mut rb_yjit_cold_threshold: u64 = 200_000; +pub static mut rb_yjit_cold_threshold: u64 = 200_000; // Command-line options #[derive(Clone, PartialEq, Eq, Debug)] @@ -92,7 +101,7 @@ static YJIT_OPTIONS: [(&str, &str); 8] = [ ("--yjit-trace-exits", "Record Ruby source location when exiting from generated code"), ("--yjit-trace-exits-sample-rate", "Trace exit locations only every Nth occurrence"), ("--yjit-exec-mem-size=num", "Size of executable memory block in MiB (default: 128)"), - ("--yjit-call-threshold=num", "Number of calls to trigger JIT (default: 30)"), + ("--yjit-call-threshold=num", "Number of calls to trigger JIT"), ("--yjit-cold-threshold=num", "Global call after which ISEQs not compiled (default: 200K)"), ("--yjit-max-versions=num", "Maximum number of versions per basic block (default: 4)"), ("--yjit-perf", "Enable frame pointers and perf profiling"), diff --git a/yjit/src/yjit.rs b/yjit/src/yjit.rs index 1e7e01a834..8431168763 100644 --- a/yjit/src/yjit.rs +++ b/yjit/src/yjit.rs @@ -134,6 +134,14 @@ pub extern "C" fn rb_yjit_iseq_gen_entry_point(iseq: IseqPtr, ec: EcPtr, jit_exc return std::ptr::null(); } + // If a custom call threshold was not specified on the command-line and + // this is a large application (has very many ISEQs), switch to + // using the call threshold for large applications after this entry point + use crate::stats::rb_yjit_live_iseq_count; + if unsafe { rb_yjit_call_threshold } == SMALL_CALL_THRESHOLD && unsafe { rb_yjit_live_iseq_count } > LARGE_ISEQ_COUNT { + unsafe { rb_yjit_call_threshold = LARGE_CALL_THRESHOLD; }; + } + let maybe_code_ptr = with_compile_time(|| { gen_entry_point(iseq, ec, jit_exception) }); match maybe_code_ptr { |