diff --git a/core/dr-inference-engine/src/probe.rs b/core/dr-inference-engine/src/probe.rs index 0338a85..d0266f6 100644 --- a/core/dr-inference-engine/src/probe.rs +++ b/core/dr-inference-engine/src/probe.rs @@ -255,9 +255,14 @@ fn probe_model(cfg: &Config) -> Option<(Role, PathBuf)> { smallest(Some(Role::Detector)).or_else(|| smallest(None)) } -/// Build, run once for the engine, then time three runs; the median in -/// milliseconds and, for a compiling rung, the cache key of the engine this -/// just built. +/// Build, warm up, then time seven runs; the median in milliseconds and, +/// for a compiling rung, the cache key of the engine this just built. +/// +/// Three warm-ups, not one: an idle integrated GPU takes a few runs to +/// raise its clock. With one, the Iris Xe's OpenVINO lost to the CPU on +/// the smallest detector in two probes of three, where warm it is 5.8 ms +/// against 9.5 (ยง1.6). The smallest detector is a GPU's worst case; the +/// clock must not also be. fn time_rung( rung: Rung, role: Role, @@ -315,11 +320,15 @@ fn time_rung( .map_err(|e| e.to_string())?; Ok(t.elapsed().as_secs_f64() * 1e3) }; - run(&mut session)?; - let mut times = [run(&mut session)?, run(&mut session)?, run(&mut session)?]; + for _ in 0..3 { + run(&mut session)?; + } + let mut times = (0..7) + .map(|_| run(&mut session)) + .collect::, _>>()?; times.sort_by(|a, b| a.partial_cmp(b).unwrap()); let key = rung.compiles().then(|| crate::engines::key(rung, &bytes)); - Ok((times[1], key)) + Ok((times[times.len() / 2], key)) } /// The part of a provider's error a person can act on. ONNX Runtime's