From bf55cef3e37aeacf3727eccdcdf47c68db6b2a3d Mon Sep 17 00:00:00 2001 From: claude-asm-audit Date: Sat, 15 Aug 2026 14:01:24 +0000 Subject: [PATCH] perf(run_queue): flip default backend rq-mutex -> rq-mpmc Evidence (history.md session 5, findings 10-11, 20-core jobrunner run): rq-mutex collapses with thread count on queue-heavy load (yield-storm 6.9x slower than striped at 20T; attributed cause of the baseline's multi-thread regression on yield_many/chained_spawn), while rq-mpmc is best-or-close everywhere: best 1-thread, best slot-on ping-pong (1237us vs mutex 6754us at 20T), -23%/-41 cyc per yield roundtrip on real hardware (single-core switch_cost, interleaved). rq-striped remains the churn-heavy many-core option, selectable per build. Docs + compile_error hints in run_queue.rs updated to name rq-mpmc as the default. slot_state.rs untouched, no loom-relevant changes; lib (60) + scheduler/channel/supervisor/park_wake/wake_slot/preempt (41) pass under the new default. --- Cargo.toml | 2 +- src/run_queue.rs | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d59be33..b80e1e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ unwrap_used = "deny" expect_used = "deny" [features] -default = ["rq-mutex"] +default = ["rq-mpmc"] smarm-trace = [] # RFC 007: native causal profiling. Zero cost when off (cf. smarm-trace): the # hook in `maybe_preempt` and the resume-path fast-forward compile away; the diff --git a/src/run_queue.rs b/src/run_queue.rs index 16656e5..6814e8b 100644 --- a/src/run_queue.rs +++ b/src/run_queue.rs @@ -2,9 +2,9 @@ //! features (no runtime dispatch — the scheduler's pop loop is the hottest //! code in the runtime): //! -//! - `rq-mutex` (default) — `Mutex`. The control/baseline: +//! - `rq-mutex` — `Mutex`. The control/baseline: //! strictly FIFO, trivially correct, one global lock. -//! - `rq-mpmc` — a single hand-rolled Vyukov bounded MPMC ring (per-cell +//! - `rq-mpmc` (default) — a single hand-rolled Vyukov bounded MPMC ring (per-cell //! sequence numbers). Strict FIFO, lock-free, one hot //! enqueue/dequeue cache-line pair. //! - `rq-striped` — M Vyukov rings with fetch-add ticket distribution. @@ -61,20 +61,20 @@ use std::mem::MaybeUninit; #[cfg(not(any(feature = "rq-mutex", feature = "rq-mpmc", feature = "rq-striped")))] compile_error!( "smarm: no run queue selected. Enable exactly one of the features \ - `rq-mutex` (default), `rq-mpmc`, `rq-striped`." + `rq-mpmc` (default), `rq-mutex`, `rq-striped`." ); #[cfg(all(feature = "rq-mutex", feature = "rq-mpmc"))] compile_error!( "smarm: features `rq-mutex` and `rq-mpmc` are mutually exclusive \ - (use --no-default-features to drop the default `rq-mutex`)." + (use --no-default-features to drop the default `rq-mpmc`)." ); #[cfg(all(feature = "rq-mutex", feature = "rq-striped"))] -compile_error!( - "smarm: features `rq-mutex` and `rq-striped` are mutually exclusive \ - (use --no-default-features to drop the default `rq-mutex`)." -); +compile_error!("smarm: features `rq-mutex` and `rq-striped` are mutually exclusive."); #[cfg(all(feature = "rq-mpmc", feature = "rq-striped"))] -compile_error!("smarm: features `rq-mpmc` and `rq-striped` are mutually exclusive."); +compile_error!( + "smarm: features `rq-mpmc` and `rq-striped` are mutually exclusive \ + (use --no-default-features to drop the default `rq-mpmc`)." +); #[cfg(feature = "rq-mutex")] pub(crate) type RunQueue = MutexQueue;