85 lines
2.5 KiB
Rust
85 lines
2.5 KiB
Rust
//! Translated from libnyx/test.c
|
|
|
|
mod benchmark;
|
|
mod benchmark_baseline;
|
|
mod benchmark_nyx_pt;
|
|
mod nyx;
|
|
|
|
use crate::benchmark::{Benchmark, ToCsv};
|
|
use crate::benchmark_baseline::Baseline;
|
|
use clap::Parser;
|
|
use std::error::Error;
|
|
use std::path::{Path, PathBuf};
|
|
use std::time::{Duration, Instant};
|
|
use crate::benchmark_nyx_pt::NyxRunner;
|
|
|
|
#[derive(Debug, Parser)]
|
|
#[command(about = "Tool to execute a program with nyx and trace it with intel pt")]
|
|
struct Args {
|
|
/// Path to the client binary to execute
|
|
client: PathBuf,
|
|
/// Directory where the benchmark files get stored
|
|
#[arg(short = 'o', long = "output", default_value = "benchmarks")]
|
|
output_dir: PathBuf,
|
|
}
|
|
|
|
fn main() -> Result<(), Box<dyn Error>> {
|
|
let args = Args::parse();
|
|
let nyx_runner = NyxRunner::setup(&args.client)?;
|
|
let binary_name = args.client.file_name().unwrap().to_str().unwrap();
|
|
benchmark(binary_name, &args.output_dir, nyx_runner)?;
|
|
benchmark(binary_name, &args.output_dir, Baseline(&args.client))?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn benchmark<B: Benchmark>(
|
|
binary_name: &str,
|
|
output_dir: &Path,
|
|
mut benchmark: B,
|
|
) -> Result<(), Box<dyn Error>> {
|
|
warmup(&mut benchmark);
|
|
let results = benchmark_loop(&mut benchmark);
|
|
write_results::<B>(binary_name, output_dir, &results)?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Warm up to make sure caches are initialized, etc.
|
|
fn warmup(benchmark: &mut impl Benchmark) {
|
|
let warmup_duration = Duration::from_secs(60);
|
|
println!("Warming up for {warmup_duration:?}");
|
|
let mut iterations = 0;
|
|
let start = Instant::now();
|
|
while start.elapsed() < warmup_duration {
|
|
benchmark.execute_once();
|
|
iterations += 1;
|
|
}
|
|
println!("Warmed up for {iterations} iterations");
|
|
}
|
|
|
|
fn benchmark_loop<B: Benchmark>(benchmark: &mut B) -> Vec<B::BenchmarkResult> {
|
|
let n = 500;
|
|
println!("Perform {n} iterations...");
|
|
(0..n)
|
|
.map(|_| std::hint::black_box(benchmark.execute_once()))
|
|
.collect::<Vec<_>>()
|
|
}
|
|
|
|
fn write_results<B: Benchmark>(
|
|
binary_name: &str,
|
|
output_dir: &Path,
|
|
results: &[B::BenchmarkResult],
|
|
) -> Result<(), Box<dyn Error>> {
|
|
std::fs::create_dir_all(output_dir)?;
|
|
let filename = format!("benchmark_{binary_name}_{}", B::TITLE);
|
|
let file = std::fs::File::create(output_dir.join(filename))?;
|
|
let mut writer = csv::WriterBuilder::new().from_writer(file);
|
|
writer.write_record(B::BenchmarkResult::HEADERS)?;
|
|
for result in results {
|
|
result.write(&mut writer)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|