Files
smarm/benches/baseline.json
Bench 3da6ffaa77 benches: expose preemption knobs + sweep runner
Config API changes (src/preempt.rs, src/runtime.rs):
- preempt: promote ALLOC_INTERVAL and TIMESLICE_CYCLES from bare consts to
  DEFAULT_ALLOC_INTERVAL / DEFAULT_TIMESLICE_CYCLES; store active values in
  thread-locals set on each actor resume so multiple runtimes can use
  different settings concurrently.
- runtime: add alloc_interval / timeslice_cycles fields to Config; add
  Config::alloc_interval(n) and Config::timeslice_cycles(c) builder methods;
  thread the values through RuntimeInner to the reset_timeslice() call in
  schedule_loop.

Bench changes:
- Add bench_cfg(threads) helper to general/tokio_favored/smarm_favored that
  wraps Config::exact and reads SMARM_ALLOC_INTERVAL / SMARM_TIMESLICE_CYCLES
  env vars, so the sweep script can vary knobs without recompiling.

Sweep tooling (benches/sweep.py):
- 'run':     run the 3-file bench suite once; --save-baseline persists JSON
- 'regress': compare current run against baseline.json, exit 1 on any bench
             that regresses >10% vs stored medians
- 'sweep':   run the full SWEEP_GRID (10 points), print comparison table,
             optional --save-csv; binaries pre-built so no recompile per point

Sweep results (10-point grid, 1-CPU sandbox):
- The preemption knobs have very little effect on this single-CPU machine.
  Most benches move <5% across the entire grid.
- Longer timeslices (tc=600k, tc=1200k) reliably hurt spawn_storm_busy
  (+11-15%) and catch_unwind_panics (+10-12%) because actors hold the
  scheduler mutex longer per timeslice, stalling the storm of joinable tasks.
- Shorter timeslices (tc=150k) give a small improvement on many_timers
  (-3-4%) and a wash everywhere else.
- yield_in_hot_loop and uncontended_channel are essentially flat across all
  knobs — both are scheduling-dominated and call yield_now explicitly, so
  the RDTSC-driven preemption path is irrelevant.
- Conclusion: the knobs matter primarily under contention (multi-core).
  Re-run sweep on a multi-core machine before drawing tuning conclusions.
2026-05-25 13:04:58 +00:00

224 lines
4.1 KiB
JSON

{
"chained_spawn": {
"smarm 1-thread": {
"result": 1000,
"median": 8637,
"min": 8553,
"max": 8933
},
"tokio current_thread": {
"result": 1000,
"median": 124,
"min": 124,
"max": 153
},
"tokio multi-thread": {
"result": 1000,
"median": 188,
"min": 183,
"max": 229
}
},
"yield_many": {
"smarm 1-thread": {
"result": 200000,
"median": 41622,
"min": 41063,
"max": 44973
},
"tokio current_thread": {
"result": 200000,
"median": 15085,
"min": 15013,
"max": 15274
},
"tokio multi-thread": {
"result": 200000,
"median": 15964,
"min": 15880,
"max": 17959
}
},
"fan_out_compute": {
"smarm 1-thread": {
"result": 33860,
"median": 29727,
"min": 29491,
"max": 31634
},
"tokio current_thread": {
"result": 33860,
"median": 28503,
"min": 28391,
"max": 28866
},
"tokio multi-thread": {
"result": 33860,
"median": 34542,
"min": 34396,
"max": 36111
}
},
"ping_pong_oneshot": {
"smarm 1-thread": {
"result": 1000,
"median": 16848,
"min": 16633,
"max": 17301
},
"tokio current_thread": {
"result": 1000,
"median": 879,
"min": 868,
"max": 973
},
"tokio multi-thread": {
"result": 1000,
"median": 4328,
"min": 4223,
"max": 4461
}
},
"spawn_storm_busy": {
"smarm 1-thread": {
"result": 10000,
"median": 130058,
"min": 126790,
"max": 134475
},
"tokio current_thread": {
"result": 10000,
"median": 2772,
"min": 2641,
"max": 4367
},
"tokio multi-thread": {
"result": 10000,
"median": 7462,
"min": 4469,
"max": 12892
}
},
"mpsc_contention": {
"smarm 1-thread": {
"result": 320000,
"median": 9260,
"min": 9095,
"max": 10081
},
"tokio current_thread": {
"result": 320000,
"median": 17570,
"min": 17213,
"max": 18276
},
"tokio multi-thread": {
"result": 320000,
"median": 17593,
"min": 17452,
"max": 19564
}
},
"many_timers": {
"smarm 1-thread": {
"result": 10000,
"median": 135806,
"min": 132573,
"max": 141651
},
"tokio current_thread": {
"result": 10000,
"median": 14462,
"min": 13555,
"max": 15457
},
"tokio multi-thread": {
"result": 10000,
"median": 15011,
"min": 14655,
"max": 15368
}
},
"multi_thread_scaling": {
"smarm 1-thread": {
"result": 33860,
"median": 30029,
"min": 29720,
"max": 31351
},
"tokio multi 1-thread": {
"result": 33860,
"median": 28983,
"min": 28908,
"max": 29323
}
},
"deep_recursion": {
"smarm 1-thread": {
"result": 1,
"median": 83,
"min": 78,
"max": 587
},
"tokio current_thread": {
"result": 1,
"median": 25,
"min": 25,
"max": 33
},
"tokio multi-thread": {
"result": 1,
"median": 59,
"min": 47,
"max": 205
}
},
"yield_in_hot_loop": {
"smarm 1-thread": {
"result": 1000000,
"median": 188753,
"min": 187007,
"max": 194366
},
"tokio current_thread": {
"result": 1000000,
"median": 153929,
"min": 152712,
"max": 158749
}
},
"uncontended_channel": {
"smarm 1-thread": {
"result": 1000000,
"median": 26811,
"min": 26498,
"max": 29069
},
"tokio current_thread": {
"result": 1000000,
"median": 51888,
"min": 51530,
"max": 52708
}
},
"catch_unwind_panics": {
"smarm 1-thread": {
"result": 10000,
"median": 142215,
"min": 140189,
"max": 143570
},
"tokio current_thread": {
"result": 10000,
"median": 682295,
"min": 670281,
"max": 700774
},
"tokio multi-thread": {
"result": 10000,
"median": 662688,
"min": 641453,
"max": 681868
}
}
}