feat(core): inference_thread_count halves on battery
Adds battery-state awareness to the thread-count helper: when probe_power_state() returns OnBattery, chosen is halved before the [MIN, MAX] clamp. Also removes the leading underscore from the workload/gpu_offloaded parameters (they are silenced via let _ = ... until the GPU-clamp task). New test battery_halves_thread_count verifies on_battery <= on_ac and >= MIN when the host has more than MIN physical cores. Restructured to sequential with_override calls (not nested) to avoid re-entrant deadlock on power::TEST_LOCK. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -40,7 +40,7 @@ const GPU_FLOOR_WHISPER: usize = 4;
|
||||
/// 3. on battery → base /= 2.
|
||||
/// 4. gpu_offloaded → base = min(base, gpu_floor(workload)).
|
||||
/// 5. clamp to [MIN_INFERENCE_THREADS, MAX_INFERENCE_THREADS].
|
||||
pub fn inference_thread_count(_workload: Workload, _gpu_offloaded: bool) -> usize {
|
||||
pub fn inference_thread_count(workload: Workload, gpu_offloaded: bool) -> usize {
|
||||
if let Ok(s) = std::env::var("MAGNOTIA_INFERENCE_THREADS") {
|
||||
if let Ok(n) = s.parse::<usize>() {
|
||||
if n > 0 {
|
||||
@@ -49,13 +49,17 @@ pub fn inference_thread_count(_workload: Workload, _gpu_offloaded: bool) -> usiz
|
||||
}
|
||||
}
|
||||
let physical = num_cpus::get_physical();
|
||||
let chosen = if physical > 0 {
|
||||
let mut chosen = if physical > 0 {
|
||||
physical
|
||||
} else {
|
||||
std::thread::available_parallelism()
|
||||
.map(|p| p.get())
|
||||
.unwrap_or(MIN_INFERENCE_THREADS)
|
||||
};
|
||||
if power::probe_power_state() == PowerState::OnBattery {
|
||||
chosen /= 2;
|
||||
}
|
||||
let _ = (workload, gpu_offloaded); // GPU clamp added in next task
|
||||
chosen.clamp(MIN_INFERENCE_THREADS, MAX_INFERENCE_THREADS)
|
||||
}
|
||||
|
||||
@@ -101,4 +105,27 @@ mod tests {
|
||||
fn workload_variants_distinct() {
|
||||
assert_ne!(Workload::Llm, Workload::Whisper);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn battery_halves_thread_count() {
|
||||
with_thread_env_lock(|| {
|
||||
std::env::remove_var("MAGNOTIA_INFERENCE_THREADS");
|
||||
// Measure on battery, then on AC — sequential, not nested,
|
||||
// to avoid re-entrant deadlock on power::TEST_LOCK.
|
||||
let on_battery = crate::power::with_override(Some(PowerState::OnBattery), || {
|
||||
inference_thread_count(Workload::Llm, false)
|
||||
});
|
||||
let on_ac = crate::power::with_override(Some(PowerState::OnAc), || {
|
||||
inference_thread_count(Workload::Llm, false)
|
||||
});
|
||||
// on_battery should be roughly half of on_ac, clamped to MIN.
|
||||
if on_ac > MIN_INFERENCE_THREADS {
|
||||
assert!(
|
||||
on_battery <= on_ac,
|
||||
"battery ({on_battery}) should be <= AC ({on_ac})"
|
||||
);
|
||||
assert!(on_battery >= MIN_INFERENCE_THREADS);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user