use super::adaptive::initial_parallelism;
use std::time::Duration;
const SCREEN_GATE_BASE_PERCENT: usize = 65;
const SCREEN_GATE_DISCOUNT_PER_WORKER: usize = 10;
const MINIMUM_SCREEN_GATE_PERCENT: usize = 20;
const SCREEN_GATE_DENOMINATOR: u128 = 100;
const MINIMUM_SAMPLE_BYTES: usize = 256 * 1024;
const MINIMUM_TASK_WAVES: usize = 2;
const MINIMUM_GRID_TASKS: usize = 16;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) struct WorkSample {
bytes: usize,
nanos: u128,
}
impl WorkSample {
pub(crate) fn new(bytes: usize, elapsed: Duration) -> Self {
Self {
bytes,
nanos: elapsed.as_nanos().max(1),
}
}
#[cfg(test)]
const fn from_nanos(bytes: usize, nanos: u128) -> Self {
Self {
bytes,
nanos: if nanos == 0 { 1 } else { nanos },
}
}
const fn is_representative(self) -> bool {
self.bytes >= MINIMUM_SAMPLE_BYTES
}
}
pub(crate) fn effective_parallelism(
configured: usize,
application_limit: usize,
machine_parallelism: usize,
task_count: usize,
) -> usize {
let two_wave_task_limit = task_count / MINIMUM_TASK_WAVES;
let budget = configured.min(application_limit).min(machine_parallelism);
initial_parallelism(budget.max(1), machine_parallelism, task_count)
.min(budget)
.min(two_wave_task_limit)
}
pub(crate) fn should_probe(effective_workers: usize, task_count: usize) -> bool {
effective_workers >= 2
&& task_count >= MINIMUM_GRID_TASKS
&& task_count >= effective_workers.saturating_mul(MINIMUM_TASK_WAVES)
}
pub(crate) fn screen_admits_marker(
effective_workers: usize,
exact: WorkSample,
speculative: WorkSample,
) -> bool {
if effective_workers < 2 || !exact.is_representative() || !speculative.is_representative() {
return false;
}
let gate_percent = SCREEN_GATE_BASE_PERCENT
.saturating_sub(effective_workers.saturating_mul(SCREEN_GATE_DISCOUNT_PER_WORKER))
.max(MINIMUM_SCREEN_GATE_PERCENT);
let marker_score = (speculative.bytes as u128)
.saturating_mul(exact.nanos)
.saturating_mul(SCREEN_GATE_DENOMINATOR);
let exact_score = (exact.bytes as u128)
.saturating_mul(speculative.nanos)
.saturating_mul(gate_percent as u128);
marker_score >= exact_score
}
#[cfg(test)]
mod tests {
use super::*;
const MIB: usize = 1024 * 1024;
#[test]
fn effective_parallelism_honors_every_bound() {
assert_eq!(effective_parallelism(8, 6, 4, 8), 4);
assert_eq!(effective_parallelism(8, 2, 4, 18), 2);
assert_eq!(effective_parallelism(1, 8, 8, 8), 1);
assert_eq!(effective_parallelism(8, 8, 8, 3), 1);
assert_eq!(effective_parallelism(8, 8, 8, 0), 0);
}
#[test]
fn probe_requires_two_complete_task_waves() {
assert!(!should_probe(1, 64));
assert!(!should_probe(2, 3));
assert!(!should_probe(2, 15));
assert!(should_probe(2, 16));
assert!(!should_probe(4, 7));
assert!(should_probe(4, 16));
}
#[test]
fn screen_gate_is_conservative_but_allows_fixed_cost_amortization() {
let exact = WorkSample::from_nanos(MIB, 1_000);
let forty_four_percent = WorkSample::from_nanos(MIB, 2_273);
let forty_five_percent = WorkSample::from_nanos(MIB, 2_222);
let twenty_four_percent = WorkSample::from_nanos(MIB, 4_167);
let twenty_five_percent = WorkSample::from_nanos(MIB, 4_000);
assert!(!screen_admits_marker(2, exact, forty_four_percent));
assert!(screen_admits_marker(2, exact, forty_five_percent));
assert!(!screen_admits_marker(4, exact, twenty_four_percent));
assert!(screen_admits_marker(4, exact, twenty_five_percent));
}
#[test]
fn large_budgets_use_the_adaptive_bootstrap() {
assert_eq!(effective_parallelism(64, 64, 64, 128), 16);
assert_eq!(effective_parallelism(64, 8, 64, 128), 6);
assert_eq!(effective_parallelism(64, 3, 64, 128), 3);
}
#[test]
fn ambiguous_samples_choose_sequential() {
let representative = WorkSample::from_nanos(MIB, 1_000);
let tiny = WorkSample::from_nanos(MINIMUM_SAMPLE_BYTES - 1, 1);
assert!(!screen_admits_marker(1, representative, representative));
assert!(!screen_admits_marker(2, tiny, representative));
assert!(!screen_admits_marker(2, representative, tiny));
}
}