[751e2eb] | 1 | use std::io::{self, Write};
|
---|
[821c534] | 2 | use std::option;
|
---|
[751e2eb] | 3 | use std::sync::atomic::{AtomicU64, AtomicBool, Ordering};
|
---|
| 4 | use std::time::{Instant,Duration};
|
---|
[821c534] | 5 | use std::u128;
|
---|
[751e2eb] | 6 |
|
---|
| 7 | use clap::{Arg, ArgMatches};
|
---|
| 8 | use isatty::stdout_isatty;
|
---|
| 9 |
|
---|
| 10 | use tokio::time;
|
---|
| 11 |
|
---|
| 12 |
|
---|
| 13 | // ==================================================
|
---|
| 14 | pub fn args<'a, 'b>() -> [Arg<'a, 'b>; 4] {[
|
---|
| 15 | Arg::with_name("duration") .short("d").long("duration") .takes_value(true).default_value("5").help("Duration of the experiments in seconds"),
|
---|
| 16 | Arg::with_name("iterations").short("i").long("iterations").takes_value(true).conflicts_with("duration").help("Number of iterations of the experiments"),
|
---|
| 17 | Arg::with_name("nthreads") .short("t").long("nthreads") .takes_value(true).default_value("1").help("Number of threads to use"),
|
---|
| 18 | Arg::with_name("nprocs") .short("p").long("nprocs") .takes_value(true).default_value("1").help("Number of processors to use")
|
---|
| 19 | ]}
|
---|
| 20 |
|
---|
| 21 | pub struct BenchData {
|
---|
| 22 | pub clock_mode: bool,
|
---|
| 23 | pub stop: AtomicBool,
|
---|
| 24 | pub stop_count: u64,
|
---|
| 25 | pub duration: f64,
|
---|
| 26 | pub threads_left: AtomicU64,
|
---|
| 27 | is_tty: bool,
|
---|
| 28 | }
|
---|
| 29 |
|
---|
| 30 | impl BenchData {
|
---|
[821c534] | 31 | pub fn new(options: ArgMatches, nthreads: usize, default_it: option::Option<u64>) -> BenchData {
|
---|
[751e2eb] | 32 | let (clock_mode, stop_count, duration) = if options.is_present("iterations") {
|
---|
| 33 | (false,
|
---|
| 34 | options.value_of("iterations").unwrap().parse::<u64>().unwrap(),
|
---|
| 35 | -1.0)
|
---|
[821c534] | 36 | } else if !default_it.is_none() {
|
---|
| 37 | (false,
|
---|
| 38 | default_it.unwrap(),
|
---|
| 39 | -1.0)
|
---|
[751e2eb] | 40 | } else {
|
---|
| 41 | (true,
|
---|
| 42 | std::u64::MAX,
|
---|
| 43 | options.value_of("duration").unwrap().parse::<f64>().unwrap())
|
---|
| 44 | };
|
---|
| 45 |
|
---|
| 46 | BenchData{
|
---|
| 47 | clock_mode: clock_mode,
|
---|
| 48 | stop: AtomicBool::new(false),
|
---|
| 49 | stop_count: stop_count,
|
---|
| 50 | duration: duration,
|
---|
| 51 | threads_left: AtomicU64::new(nthreads as u64),
|
---|
| 52 | is_tty: stdout_isatty(),
|
---|
| 53 | }
|
---|
| 54 | }
|
---|
| 55 |
|
---|
[821c534] | 56 | #[allow(dead_code)]
|
---|
[751e2eb] | 57 | pub async fn wait(&self, start: &Instant) -> Duration{
|
---|
| 58 | loop {
|
---|
| 59 | time::sleep(Duration::from_micros(100000)).await;
|
---|
| 60 | let delta = start.elapsed();
|
---|
| 61 | if self.is_tty {
|
---|
| 62 | print!(" {:.1}\r", delta.as_secs_f32());
|
---|
| 63 | io::stdout().flush().unwrap();
|
---|
| 64 | }
|
---|
| 65 | if self.clock_mode && delta >= Duration::from_secs_f64(self.duration) {
|
---|
| 66 | break;
|
---|
| 67 | }
|
---|
| 68 | else if !self.clock_mode && self.threads_left.load(Ordering::Relaxed) == 0 {
|
---|
| 69 | break;
|
---|
| 70 | }
|
---|
| 71 | }
|
---|
| 72 |
|
---|
| 73 | self.stop.store(true, Ordering::SeqCst);
|
---|
| 74 | return start.elapsed();
|
---|
| 75 | }
|
---|
| 76 | }
|
---|
| 77 |
|
---|
[821c534] | 78 | // ==================================================
|
---|
| 79 | pub fn _lehmer64( state: &mut u128 ) -> u64 {
|
---|
| 80 | *state = state.wrapping_mul(0xda942042e4dd58b5);
|
---|
| 81 | return (*state >> 64) as u64;
|
---|
| 82 | }
|
---|