Skip to content

Instantly share code, notes, and snippets.

@mooreniemi
Created November 11, 2024 03:59
Show Gist options
  • Select an option

  • Save mooreniemi/2e1c37ae03c191344ba6e8a93a8bc58c to your computer and use it in GitHub Desktop.

Select an option

Save mooreniemi/2e1c37ae03c191344ba6e8a93a8bc58c to your computer and use it in GitHub Desktop.

Revisions

  1. mooreniemi created this gist Nov 11, 2024.
    76 changes: 76 additions & 0 deletions time_logging.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,76 @@
    use std::time::{Duration, Instant, SystemTime};
    use std::hint::black_box;
    use clap::Parser;

    #[derive(Parser, Debug)]
    #[command(author, version, about, long_about = None)]
    struct Args {
    /// Number of outer iterations for each timing method
    #[arg(long, default_value_t = 15_000)]
    iterations: u64,

    /// Number of time measurements per iteration
    #[arg(long, default_value_t = 10)]
    measurements_per_iter: u64,
    }

    #[cfg(target_arch = "aarch64")]
    #[inline(always)]
    fn read_cycle_counter() -> u64 {
    // CNTVCT_EL0 is the virtual counter register on ARM
    unsafe {
    let val: u64;
    std::arch::asm!("mrs {}, CNTVCT_EL0", out(reg) val);
    val
    }
    }

    #[cfg(target_arch = "x86_64")]
    #[inline(always)]
    fn read_cycle_counter() -> u64 {
    unsafe { std::arch::x86_64::_rdtsc() }
    }

    fn main() {
    let args = Args::parse();
    println!("Running with args: {:?}", args);

    // Benchmark SystemTime
    let start = Instant::now();
    for _ in 0..args.iterations {
    for _ in 0..args.measurements_per_iter {
    black_box(SystemTime::now());
    }
    }
    let system_time_duration = start.elapsed();

    // Benchmark Instant (monotonic clock)
    let start = Instant::now();
    for _ in 0..args.iterations {
    for _ in 0..args.measurements_per_iter {
    black_box(Instant::now());
    }
    }
    let instant_duration = start.elapsed();

    // Benchmark CPU cycles
    let cycles_duration = {
    let start = Instant::now();
    for _ in 0..args.iterations {
    for _ in 0..args.measurements_per_iter {
    black_box(read_cycle_counter());
    }
    }
    start.elapsed()
    };

    let total_measurements = args.iterations * args.measurements_per_iter;
    println!("Time measurements over {} total measurements ({} iterations × {} per iteration):",
    total_measurements, args.iterations, args.measurements_per_iter);
    println!("SystemTime::now(): {:?} ({:?} per call)",
    system_time_duration, system_time_duration / total_measurements as u32);
    println!("Instant::now(): {:?} ({:?} per call)",
    instant_duration, instant_duration / total_measurements as u32);
    println!("CPU cycles: {:?} ({:?} per call)",
    cycles_duration, cycles_duration / total_measurements as u32);
    }