Skip to content

Commit

Permalink
YJIT: try request count warmup heuristic
Browse files Browse the repository at this point in the history
Make req count configurable through options
  • Loading branch information
maximecb committed Jul 17, 2023
1 parent 105bdba commit c7e6657
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 3 deletions.
13 changes: 13 additions & 0 deletions yjit/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ pub struct Options {
// Threshold==1 means compile on first execution
pub call_threshold: usize,

// How many compilation requests to skip before compiling new code
// This is used to let some execution proceed when we are compiling
// a lot of new code, to make warmup more gradual for heavy workloads
pub jit_interv: usize,

// Generate versions greedily until the limit is hit
pub greedy_versioning: bool,

Expand Down Expand Up @@ -56,6 +61,7 @@ pub struct Options {
pub static mut OPTIONS: Options = Options {
exec_mem_size: 128 * 1024 * 1024,
call_threshold: 30,
jit_interv: 120,
greedy_versioning: false,
no_type_prop: false,
max_versions: 4,
Expand Down Expand Up @@ -139,6 +145,13 @@ pub fn parse_option(str_ptr: *const std::os::raw::c_char) -> Option<()> {
}
},

("jit-interv", _) => match opt_val.parse() {
Ok(n) => unsafe { OPTIONS.jit_interv = n },
Err(_) => {
return None;
}
},

("max-versions", _) => match opt_val.parse() {
Ok(n) => unsafe { OPTIONS.max_versions = n },
Err(_) => {
Expand Down
19 changes: 16 additions & 3 deletions yjit/src/yjit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ use crate::stats::YjitExitLocations;
use crate::stats::incr_counter;

use std::os::raw;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};

/// For tracking whether the user enabled YJIT through command line arguments or environment
/// variables. AtomicBool to avoid `unsafe`. On x86 it compiles to simple movs.
/// See <https://doc.rust-lang.org/std/sync/atomic/enum.Ordering.html>
/// See [rb_yjit_enabled_p]
static YJIT_ENABLED: AtomicBool = AtomicBool::new(false);

/// How many compilation requests YJIT received in total
static YJIT_REQUEST_COUNT: AtomicUsize = AtomicUsize::new(0);

/// When false, we don't compile new iseqs, but might still service existing branch stubs.
static COMPILE_NEW_ISEQS: AtomicBool = AtomicBool::new(false);

Expand Down Expand Up @@ -49,10 +52,20 @@ pub fn yjit_enabled_p() -> bool {
#[no_mangle]
pub extern "C" fn rb_yjit_threshold_hit(iseq: IseqPtr) -> bool {

let call_threshold = get_option!(call_threshold) as u64;
let total_calls = unsafe { rb_get_iseq_body_total_calls(iseq) } as u64;

return total_calls == call_threshold;
if total_calls < get_option!(call_threshold) as u64 {
return false;
}

// Increment the request count
let req_count: usize = YJIT_REQUEST_COUNT.fetch_add(1, Ordering::Relaxed);

if req_count % get_option!(jit_interv) == 0 {
return true;
}

return false;
}

/// This function is called from C code
Expand Down

0 comments on commit c7e6657

Please sign in to comment.