From d98d4208247aca137a490dc92599b19720f1b7b3 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 14 Sep 2019 10:29:20 -0400 Subject: [PATCH] extract cpu_time, add to noop demo --- rayon-demo/src/cpu_time/mod.rs | 55 ++++++++++++++++++++++ rayon-demo/src/{life => }/cpu_time/unix.rs | 0 rayon-demo/src/{life => }/cpu_time/win.rs | 0 rayon-demo/src/life/cpu_time/mod.rs | 20 -------- rayon-demo/src/life/mod.rs | 17 +++---- rayon-demo/src/main.rs | 1 + rayon-demo/src/noop/mod.rs | 13 +++-- 7 files changed, 71 insertions(+), 35 deletions(-) create mode 100644 rayon-demo/src/cpu_time/mod.rs rename rayon-demo/src/{life => }/cpu_time/unix.rs (100%) rename rayon-demo/src/{life => }/cpu_time/win.rs (100%) delete mode 100644 rayon-demo/src/life/cpu_time/mod.rs diff --git a/rayon-demo/src/cpu_time/mod.rs b/rayon-demo/src/cpu_time/mod.rs new file mode 100644 index 000000000..0294b0d38 --- /dev/null +++ b/rayon-demo/src/cpu_time/mod.rs @@ -0,0 +1,55 @@ +use time::{self, Duration}; + +#[cfg(windows)] +mod win; +#[cfg(windows)] +pub use self::win::get_cpu_time; + +#[cfg(unix)] +mod unix; +#[cfg(unix)] +pub use self::unix::get_cpu_time; + +#[cfg(not(any(unix, windows)))] +pub fn get_cpu_time() -> Option { + None +} + +pub fn get_cpu_duration(start: Option, stop: Option) -> Option { + start.and_then(|start| stop.and_then(|stop| Some(Duration::nanoseconds((stop - start) as i64)))) +} + +#[derive(Copy, Clone)] +pub struct CpuMeasure { + /// number of ns + pub time_duration: u64, + + /// percentage (0-100) of that as cpu time + pub cpu_usage_percent: Option, +} + +pub fn measure_cpu(op: impl FnOnce()) -> CpuMeasure { + let time_start = time::precise_time_ns(); + let cpu_start = get_cpu_time(); + + op(); + + let cpu_stop = get_cpu_time(); + let time_duration = time::precise_time_ns() - time_start; + + CpuMeasure { + time_duration, + cpu_usage_percent: get_cpu_duration(cpu_start, cpu_stop) + .and_then(|cpu| cpu.num_nanoseconds()) + .and_then(|cpu| Some(100.0 * cpu as f64 / time_duration as f64)), + } +} + +pub fn print_time(m: CpuMeasure) { + println!(" wallclock: {} ns", m.time_duration); + if let Some(cpu_usage) = m.cpu_usage_percent { + println!(" cpu usage: {:3.1}%", cpu_usage); + } else { + println!(" cpu usage: N/A"); + } +} diff --git a/rayon-demo/src/life/cpu_time/unix.rs b/rayon-demo/src/cpu_time/unix.rs similarity index 100% rename from rayon-demo/src/life/cpu_time/unix.rs rename to rayon-demo/src/cpu_time/unix.rs diff --git a/rayon-demo/src/life/cpu_time/win.rs b/rayon-demo/src/cpu_time/win.rs similarity index 100% rename from rayon-demo/src/life/cpu_time/win.rs rename to rayon-demo/src/cpu_time/win.rs diff --git a/rayon-demo/src/life/cpu_time/mod.rs b/rayon-demo/src/life/cpu_time/mod.rs deleted file mode 100644 index 4c7474887..000000000 --- a/rayon-demo/src/life/cpu_time/mod.rs +++ /dev/null @@ -1,20 +0,0 @@ -use time::Duration; - -#[cfg(windows)] -mod win; -#[cfg(windows)] -pub use self::win::get_cpu_time; - -#[cfg(unix)] -mod unix; -#[cfg(unix)] -pub use self::unix::get_cpu_time; - -#[cfg(not(any(unix, windows)))] -pub fn get_cpu_time() -> Option { - None -} - -pub fn get_cpu_duration(start: Option, stop: Option) -> Option { - start.and_then(|start| stop.and_then(|stop| Some(Duration::nanoseconds((stop - start) as i64)))) -} diff --git a/rayon-demo/src/life/mod.rs b/rayon-demo/src/life/mod.rs index b63cc2126..686a866e4 100644 --- a/rayon-demo/src/life/mod.rs +++ b/rayon-demo/src/life/mod.rs @@ -14,6 +14,7 @@ Options: -h, --help Show this message. "; +use cpu_time::{self, CpuMeasure}; use rand::distributions::Standard; use rand::{thread_rng, Rng}; use std::iter::repeat; @@ -28,7 +29,6 @@ use rayon::prelude::*; #[cfg(test)] mod bench; -mod cpu_time; #[derive(Deserialize)] pub struct Args { @@ -249,19 +249,14 @@ fn measure_cpu(f: fn(Board, usize, u64) -> (), args: &Args) -> CpuResult { let (n, gens, rate) = (args.flag_size, args.flag_gens, args.flag_fps); let interval = 1_000_000_000 / rate as u64; let brd = Board::new(n, n).random(); - let start = time::precise_time_ns(); - let cpu_start = cpu_time::get_cpu_time(); - - f(brd, gens, interval); - let cpu_stop = cpu_time::get_cpu_time(); - let duration = time::precise_time_ns() - start; + let CpuMeasure { time_duration, cpu_usage_percent } = cpu_time::measure_cpu(|| { + f(brd, gens, interval) + }); CpuResult { - actual_fps: (1_000_000_000.0 * gens as f64) / duration as f64, - cpu_usage_percent: cpu_time::get_cpu_duration(cpu_start, cpu_stop) - .and_then(|cpu| cpu.num_nanoseconds()) - .and_then(|cpu| Some(100.0 * cpu as f64 / duration as f64)), + actual_fps: (1_000_000_000.0 * gens as f64) / time_duration as f64, + cpu_usage_percent, } } diff --git a/rayon-demo/src/main.rs b/rayon-demo/src/main.rs index 807338a42..492ec93c0 100644 --- a/rayon-demo/src/main.rs +++ b/rayon-demo/src/main.rs @@ -5,6 +5,7 @@ use std::io; use std::io::prelude::*; use std::process::exit; +mod cpu_time; mod life; mod matmul; mod mergesort; diff --git a/rayon-demo/src/noop/mod.rs b/rayon-demo/src/noop/mod.rs index cb774fae0..ce06e389e 100644 --- a/rayon-demo/src/noop/mod.rs +++ b/rayon-demo/src/noop/mod.rs @@ -8,6 +8,7 @@ Options: --iters N Total time to execution (in millis). [default: 100] "; +use cpu_time; use docopt::Docopt; #[derive(Deserialize)] @@ -21,8 +22,12 @@ pub fn main(args: &[String]) { .and_then(|d| d.argv(args).deserialize()) .unwrap_or_else(|e| e.exit()); - for _ in 1..args.flag_iters { - std::thread::sleep(std::time::Duration::from_millis(args.flag_sleep)); - rayon::spawn(move || { } ); - } + let m = cpu_time::measure_cpu(|| { + for _ in 1..args.flag_iters { + std::thread::sleep(std::time::Duration::from_millis(args.flag_sleep)); + rayon::spawn(move || { } ); + } + }); + println!("noop --iters={} --sleep={}", args.flag_iters, args.flag_sleep); + cpu_time::print_time(m); }