pub const HEAVY_ENTER_PCT: u64 = 10; pub const HEAVY_EXIT_PCT: u64 = 25; pub const LIGHT_ENTER_PCT: u64 = 50; pub const LIGHT_EXIT_PCT: u64 = 30;
const LIGHT_SLICE_NS: u64 = 2_000_000; const LIGHT_PREEMPT_NS: u64 = 1_000_000; const LIGHT_LAG_SCALE: u64 = 6;
const LIGHT_BATCH_NS: u64 = 20_000_000;
const MIXED_SLICE_NS: u64 = 1_000_000; const MIXED_PREEMPT_NS: u64 = 1_000_000; const MIXED_LAG_SCALE: u64 = 4;
const MIXED_BATCH_NS: u64 = 20_000_000;
const HEAVY_SLICE_NS: u64 = 4_000_000; const HEAVY_PREEMPT_NS: u64 = 2_000_000; const HEAVY_LAG_SCALE: u64 = 2;
const HEAVY_BATCH_NS: u64 = 20_000_000;
const LIGHT_P99_CEIL_NS: u64 = 3_000_000; const MIXED_P99_CEIL_NS: u64 = 5_000_000; const HEAVY_P99_CEIL_NS: u64 = 10_000_000;
pub const DEFAULT_LAT_CRI_THRESH_HIGH: u64 = 32; pub const DEFAULT_LAT_CRI_THRESH_LOW: u64 = 8;
pub const AFFINITY_OFF: u64 = 0;
pub const AFFINITY_WEAK: u64 = 1;
pub const AFFINITY_STRONG: u64 = 2;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct TuningKnobs {
pub slice_ns: u64,
pub preempt_thresh_ns: u64,
pub lag_scale: u64,
pub batch_slice_ns: u64,
pub lat_cri_thresh_high: u64,
pub lat_cri_thresh_low: u64,
pub affinity_mode: u64,
pub sojourn_thresh_ns: u64,
pub burst_slice_ns: u64,
pub topology_tau_ns: u64,
pub codel_eq_ns: u64,
}
impl Default for TuningKnobs {
fn default() -> Self {
Self {
slice_ns: 1_000_000,
preempt_thresh_ns: 1_000_000,
lag_scale: 4,
batch_slice_ns: 20_000_000,
lat_cri_thresh_high: DEFAULT_LAT_CRI_THRESH_HIGH,
lat_cri_thresh_low: DEFAULT_LAT_CRI_THRESH_LOW,
affinity_mode: AFFINITY_OFF,
sojourn_thresh_ns: 5_000_000,
burst_slice_ns: 1_000_000,
topology_tau_ns: 0,
codel_eq_ns: 0,
}
}
}
#[repr(u8)]
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Regime {
Light = 0,
Mixed = 1,
Heavy = 2,
}
impl Regime {
pub fn label(self) -> &'static str {
match self {
Self::Light => "LIGHT",
Self::Mixed => "MIXED",
Self::Heavy => "HEAVY",
}
}
pub fn p99_ceiling(self) -> u64 {
match self {
Self::Light => LIGHT_P99_CEIL_NS,
Self::Mixed => MIXED_P99_CEIL_NS,
Self::Heavy => HEAVY_P99_CEIL_NS,
}
}
}
pub fn regime_knobs(r: Regime) -> TuningKnobs {
match r {
Regime::Light => TuningKnobs {
slice_ns: LIGHT_SLICE_NS,
preempt_thresh_ns: LIGHT_PREEMPT_NS,
lag_scale: LIGHT_LAG_SCALE,
batch_slice_ns: LIGHT_BATCH_NS,
lat_cri_thresh_high: DEFAULT_LAT_CRI_THRESH_HIGH,
lat_cri_thresh_low: DEFAULT_LAT_CRI_THRESH_LOW,
affinity_mode: AFFINITY_WEAK,
sojourn_thresh_ns: 5_000_000,
burst_slice_ns: 1_000_000,
topology_tau_ns: 0,
codel_eq_ns: 0,
},
Regime::Mixed => TuningKnobs {
slice_ns: MIXED_SLICE_NS,
preempt_thresh_ns: MIXED_PREEMPT_NS,
lag_scale: MIXED_LAG_SCALE,
batch_slice_ns: MIXED_BATCH_NS,
lat_cri_thresh_high: DEFAULT_LAT_CRI_THRESH_HIGH,
lat_cri_thresh_low: DEFAULT_LAT_CRI_THRESH_LOW,
affinity_mode: AFFINITY_STRONG,
sojourn_thresh_ns: 5_000_000,
burst_slice_ns: 1_000_000,
topology_tau_ns: 0,
codel_eq_ns: 0,
},
Regime::Heavy => TuningKnobs {
slice_ns: HEAVY_SLICE_NS,
preempt_thresh_ns: HEAVY_PREEMPT_NS,
lag_scale: HEAVY_LAG_SCALE,
batch_slice_ns: HEAVY_BATCH_NS,
lat_cri_thresh_high: DEFAULT_LAT_CRI_THRESH_HIGH,
lat_cri_thresh_low: DEFAULT_LAT_CRI_THRESH_LOW,
affinity_mode: AFFINITY_WEAK,
sojourn_thresh_ns: 5_000_000,
burst_slice_ns: 1_000_000,
topology_tau_ns: 0,
codel_eq_ns: 0,
},
}
}
const K_SLICE_CAP_Q16: u64 = 9830; const K_PREEMPT_CAP_Q16: u64 = 4915; const K_BATCH_CAP_Q16: u64 = 98304; const K_SOJOURN_Q16: u64 = 9830;
const K_FORK_STORM_RATE_Q16: u64 = 13107; const FORK_STORM_RATE_FLOOR: u64 = 200;
#[inline]
fn scale_tau_u64(tau_ns: u64, k_q16: u64) -> u64 {
(tau_ns as u128 * k_q16 as u128 >> 16) as u64
}
pub fn scaled_regime_knobs(r: Regime, _nr_cpus: u64, tau_ns: u64) -> TuningKnobs {
let mut knobs = regime_knobs(r);
let slice_cap_tau = scale_tau_u64(tau_ns, K_SLICE_CAP_Q16).clamp(500_000, 8_000_000);
let preempt_cap_tau = scale_tau_u64(tau_ns, K_PREEMPT_CAP_Q16).clamp(250_000, 4_000_000);
let sojourn_tau = scale_tau_u64(tau_ns, K_SOJOURN_Q16).clamp(2_000_000, 6_000_000);
knobs.slice_ns = knobs.slice_ns.min(slice_cap_tau);
knobs.preempt_thresh_ns = knobs.preempt_thresh_ns.min(preempt_cap_tau);
if matches!(r, Regime::Mixed) {
let batch_cap_tau = scale_tau_u64(tau_ns, K_BATCH_CAP_Q16).clamp(10_000_000, 80_000_000);
knobs.batch_slice_ns = knobs.batch_slice_ns.min(batch_cap_tau);
}
knobs.sojourn_thresh_ns = sojourn_tau;
knobs
}
pub fn detect_regime(current: Regime, idle_pct: u64) -> Regime {
match current {
Regime::Light => {
if idle_pct < LIGHT_EXIT_PCT {
Regime::Mixed
} else {
Regime::Light
}
}
Regime::Mixed => {
if idle_pct > LIGHT_ENTER_PCT {
Regime::Light
} else if idle_pct < HEAVY_ENTER_PCT {
Regime::Heavy
} else {
Regime::Mixed
}
}
Regime::Heavy => {
if idle_pct > HEAVY_EXIT_PCT {
Regime::Mixed
} else {
Regime::Heavy
}
}
}
}
pub const STABILITY_THRESHOLD: u32 = 10;
pub fn compute_stability_score(
prev_score: u32,
regime_changed: bool,
reflex_events_delta: u64,
p99_ns: u64,
p99_ceiling_ns: u64,
) -> u32 {
if regime_changed || reflex_events_delta > 0 || p99_ns > p99_ceiling_ns / 2 {
return 0;
}
(prev_score + 1).min(STABILITY_THRESHOLD)
}
pub fn should_print_telemetry(tick_counter: u64, stability_score: u32) -> bool {
if stability_score >= STABILITY_THRESHOLD {
tick_counter % 2 == 0
} else {
true
}
}
pub const HIST_BUCKETS: usize = 12;
pub const HIST_EDGES_NS: [u64; HIST_BUCKETS] = [
10_000, 25_000, 50_000, 100_000, 250_000, 500_000, 1_000_000, 2_000_000, 5_000_000, 10_000_000, 20_000_000, u64::MAX, ];
pub fn compute_p99_from_histogram(counts: &[u64; HIST_BUCKETS]) -> u64 {
let total: u64 = counts.iter().sum();
if total == 0 {
return 0;
}
let threshold = (total * 99 + 99) / 100;
let mut cumulative = 0u64;
for i in 0..HIST_BUCKETS {
cumulative += counts[i];
if cumulative >= threshold {
return HIST_EDGES_NS[i].min(HIST_EDGES_NS[HIST_BUCKETS - 2]);
}
}
HIST_EDGES_NS[HIST_BUCKETS - 2]
}
const N_EXPERTS: usize = 6;
const ETA: f64 = 8.0;
const RELAX_RATE: f64 = 0.80;
const SPIKE_CONFIRM: u32 = 2;
const RELAX_HOLD: u32 = 2;
const RELAX_CEIL_PCT: f64 = 0.70;
const EQUILIBRIUM: [f64; N_EXPERTS] = [0.08, 0.44, 0.12, 0.12, 0.12, 0.12];
const WEIGHT_FLOOR: f64 = 1e-6;
const EX_LATENCY: usize = 0;
const EX_BALANCED: usize = 1;
const EX_THROUGHPUT: usize = 2;
const EX_IO_HEAVY: usize = 3;
const EX_FORK_STORM: usize = 4;
const EX_SATURATED: usize = 5;
const SC_SLICE: [f64; 6] = [0.74, 1.00, 1.23, 0.98, 0.49, 1.47];
const SC_PREEMPT: [f64; 6] = [0.74, 1.00, 1.23, 0.98, 0.49, 1.47];
const SC_BATCH: [f64; 6] = [0.78, 1.00, 1.30, 1.30, 0.52, 1.04];
const SC_LCRI_HI: [f64; 6] = [0.74, 1.00, 1.23, 0.98, 0.98, 0.98];
const SC_LCRI_LO: [f64; 6] = [0.70, 1.00, 1.40, 0.93, 0.93, 0.93];
const SC_SOJOURN: [f64; 6] = [0.80, 1.00, 1.60, 0.93, 0.53, 1.07];
const SC_BURST: [f64; 6] = [0.74, 1.00, 1.47, 0.98, 0.49, 1.23];
const DV_LAG: [u64; 6] = [6, 4, 3, 4, 4, 3];
const DV_AFFINITY: [u64; 6] = [
AFFINITY_STRONG,
AFFINITY_STRONG,
AFFINITY_WEAK,
AFFINITY_WEAK,
AFFINITY_OFF,
AFFINITY_WEAK,
];
fn blend_continuous(base: u64, scales: &[f64; 6], w: &[f64; N_EXPERTS]) -> u64 {
let v: f64 = (0..N_EXPERTS).map(|i| w[i] * base as f64 * scales[i]).sum();
(v.round() as u64).max(1)
}
fn majority_discrete(values: &[u64; 6], w: &[f64; N_EXPERTS]) -> u64 {
let mut best_val = values[0];
let mut best_w = 0.0f64;
for &v in values.iter() {
let total: f64 = (0..N_EXPERTS)
.filter(|&i| values[i] == v)
.map(|i| w[i])
.sum();
if total > best_w {
best_w = total;
best_val = v;
}
}
best_val
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum IoBucket {
Low,
Mid,
High,
}
pub fn io_bucket(io_pct: u64) -> IoBucket {
if io_pct > 60 {
IoBucket::High
} else if io_pct < 15 {
IoBucket::Low
} else {
IoBucket::Mid
}
}
pub struct MwuSignals {
pub p99_ns: u64,
pub interactive_p99_ns: u64,
pub io_pct: u64,
pub rescue_count: u64,
pub wakeup_rate: u64,
}
#[derive(Clone, Copy, Debug, Default)]
pub struct OscillatorState {
pub codel_target_ns: u64,
pub codel_target_floor_ns: u64,
pub codel_target_max_ns: u64,
}
impl OscillatorState {
pub fn position(&self) -> f64 {
if self.codel_target_max_ns == 0 || self.codel_target_floor_ns >= self.codel_target_max_ns {
return 0.5;
}
let range = (self.codel_target_max_ns - self.codel_target_floor_ns) as f64;
let pos = self
.codel_target_ns
.saturating_sub(self.codel_target_floor_ns) as f64;
(pos / range).clamp(0.0, 1.0)
}
}
pub struct MwuController {
weights: [f64; N_EXPERTS],
baseline: TuningKnobs,
spike_streak: u32,
healthy_streak: u32,
fork_streak: u32,
prev_io_bucket: IoBucket,
prev_rescuing: bool,
losses_applied: bool,
}
impl MwuController {
pub fn new(baseline: TuningKnobs) -> Self {
Self {
weights: EQUILIBRIUM,
baseline,
spike_streak: 0,
healthy_streak: 0,
fork_streak: 0,
prev_io_bucket: IoBucket::Mid,
prev_rescuing: false,
losses_applied: false,
}
}
pub fn reset(&mut self) {
self.weights = EQUILIBRIUM;
self.spike_streak = 0;
self.healthy_streak = 0;
self.fork_streak = 0;
self.prev_io_bucket = IoBucket::Mid;
self.prev_rescuing = false;
self.losses_applied = false;
}
pub fn set_baseline(&mut self, baseline: TuningKnobs) {
self.baseline = baseline;
}
pub fn update(
&mut self,
sig: &MwuSignals,
ceiling: u64,
_nr_cpus: u64,
tau_ns: u64,
osc: &OscillatorState,
) -> TuningKnobs {
let worst = sig.p99_ns.max(sig.interactive_p99_ns);
let above = worst > ceiling;
let below_relax = (worst as f64) < (ceiling as f64 * RELAX_CEIL_PCT);
let osc_pos = osc.position();
let osc_already_tight = osc_pos < 0.40;
let osc_already_loose = osc_pos > 0.90;
let defer_to_oscillator = osc_already_tight || osc_already_loose;
let mut losses = [0.0f64; N_EXPERTS];
let mut has_loss = false;
if above {
self.healthy_streak = 0;
self.spike_streak += 1;
if self.spike_streak >= SPIKE_CONFIRM {
let v = ((worst - ceiling) as f64 / ceiling as f64).min(3.0);
losses[EX_BALANCED] += v * 0.5;
losses[EX_THROUGHPUT] += v * 1.0;
losses[EX_IO_HEAVY] += v * 0.6;
losses[EX_FORK_STORM] += v * 0.3;
losses[EX_SATURATED] += v * 0.9;
has_loss = true;
}
} else {
self.spike_streak = 0;
}
let rescuing = sig.rescue_count > 0;
if rescuing && !self.prev_rescuing && !defer_to_oscillator {
let v = (sig.rescue_count as f64 * 1.5).min(3.0);
losses[EX_LATENCY] += v * 0.4;
losses[EX_THROUGHPUT] += v * 0.6;
losses[EX_SATURATED] += v * 0.6;
losses[EX_IO_HEAVY] += v * 0.4;
losses[EX_BALANCED] += v * 0.2;
has_loss = true;
}
self.prev_rescuing = rescuing;
let cur_io = io_bucket(sig.io_pct);
if cur_io != self.prev_io_bucket {
match cur_io {
IoBucket::High => {
let v = ((sig.io_pct as f64 - 60.0) / 40.0).min(1.0);
for i in 0..N_EXPERTS {
if i != EX_IO_HEAVY {
losses[i] += v * 0.8;
}
}
has_loss = true;
}
IoBucket::Low => {
let v = ((15.0 - sig.io_pct as f64) / 15.0).clamp(0.0, 1.0);
losses[EX_IO_HEAVY] += v * 1.0;
has_loss = true;
}
IoBucket::Mid => {}
}
}
self.prev_io_bucket = cur_io;
let fork_thresh = scale_tau_u64(tau_ns, K_FORK_STORM_RATE_Q16).max(FORK_STORM_RATE_FLOOR);
let fork_storm = sig.wakeup_rate > fork_thresh && sig.rescue_count > 0;
if fork_storm {
self.fork_streak += 1;
if self.fork_streak >= SPIKE_CONFIRM && !defer_to_oscillator {
let denom = fork_thresh.max(1) as f64;
let v = ((sig.wakeup_rate as f64 / denom) - 1.0).clamp(0.0, 3.0);
losses[EX_BALANCED] += v * 0.30;
losses[EX_THROUGHPUT] += v * 1.00;
losses[EX_IO_HEAVY] += v * 0.50;
losses[EX_SATURATED] += v * 0.80;
has_loss = true;
}
} else {
self.fork_streak = 0;
}
if has_loss {
for i in 0..N_EXPERTS {
if losses[i] > 0.0 {
self.weights[i] *= (-ETA * losses[i]).exp();
}
if self.weights[i] < WEIGHT_FLOOR {
self.weights[i] = WEIGHT_FLOOR;
}
}
let sum: f64 = self.weights.iter().sum();
for w in self.weights.iter_mut() {
*w /= sum;
}
}
if !has_loss && below_relax {
self.healthy_streak += 1;
if self.healthy_streak >= RELAX_HOLD {
for i in 0..N_EXPERTS {
self.weights[i] =
(1.0 - RELAX_RATE) * self.weights[i] + RELAX_RATE * EQUILIBRIUM[i];
}
}
} else if !has_loss {
self.healthy_streak = 0;
}
self.losses_applied = has_loss;
let b = &self.baseline;
let blended_slice = blend_continuous(b.slice_ns, &SC_SLICE, &self.weights);
let blended_burst = blend_continuous(b.burst_slice_ns, &SC_BURST, &self.weights);
let mut blended_sojourn = blend_continuous(b.sojourn_thresh_ns, &SC_SOJOURN, &self.weights);
let sojourn_floor = 4_000_000u64.saturating_add(blended_slice);
if blended_sojourn < sojourn_floor {
blended_sojourn = sojourn_floor;
}
TuningKnobs {
slice_ns: blended_slice,
preempt_thresh_ns: blend_continuous(b.preempt_thresh_ns, &SC_PREEMPT, &self.weights),
lag_scale: majority_discrete(&DV_LAG, &self.weights),
batch_slice_ns: blend_continuous(b.batch_slice_ns, &SC_BATCH, &self.weights),
lat_cri_thresh_high: blend_continuous(
b.lat_cri_thresh_high,
&SC_LCRI_HI,
&self.weights,
),
lat_cri_thresh_low: blend_continuous(b.lat_cri_thresh_low, &SC_LCRI_LO, &self.weights),
affinity_mode: majority_discrete(&DV_AFFINITY, &self.weights),
sojourn_thresh_ns: blended_sojourn,
burst_slice_ns: blended_burst,
topology_tau_ns: 0,
codel_eq_ns: 0,
}
}
pub fn had_losses(&self) -> bool {
self.losses_applied
}
pub fn scale(&self) -> f64 {
let s: f64 = (0..N_EXPERTS).map(|i| self.weights[i] * SC_SLICE[i]).sum();
s
}
}