diff --git a/Cargo.lock b/Cargo.lock index 29c15c906..18cfc8f5b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -396,6 +396,27 @@ dependencies = [ "typenum", ] +[[package]] +name = "csv" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde_core", +] + +[[package]] +name = "csv-core" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782" +dependencies = [ + "memchr", +] + [[package]] name = "darling" version = "0.20.11" @@ -1649,18 +1670,28 @@ checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -1945,6 +1976,7 @@ dependencies = [ "chrono", "clap", "crossbeam", + "csv", "fs_extra", "git2", "nvml-wrapper", diff --git a/Cargo.toml b/Cargo.toml index 2a537d8dd..5dfc06468 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,3 +20,4 @@ nvml-wrapper = "0.11.0" regex = "1.11" git2 = "0.20" fs_extra = "1.3.0" +csv = "1.3" diff --git a/src/metrics/large_scenes.rs b/src/metrics/large_scenes.rs index fd0f3231e..aae4a9266 100644 --- a/src/metrics/large_scenes.rs +++ b/src/metrics/large_scenes.rs @@ -1,6 +1,6 @@ use std::{ collections::HashMap, - io::Write, + io::{BufRead, Write}, path::{Path, PathBuf}, thread, time::{Duration, Instant}, @@ -122,9 +122,17 @@ impl Metrics for LargeScene { .into_iter() .flat_map(|f| ["--features".to_string(), f]); + let _guard = sh.push_env( + "MANGOHUD_CONFIG", + format!( + "output_folder={},autostart_log=10", + std::env::current_dir().unwrap().display() + ), + ); + let cmd = cmd!( sh, - "xvfb-run cargo run --release {features...} --package {scene} -- {parameters...}" + "xvfb-run mangohud cargo run --release {features...} --package {scene} -- {parameters...}" ); let mut results = HashMap::new(); @@ -228,6 +236,58 @@ impl Metrics for LargeScene { results.insert(format!("{key}.duration"), elapsed.as_millis() as u64); results.insert(format!("{key}.frames"), self.nb_frames as u64); + if let Some(last_modified_file) = std::fs::read_dir(".") + .expect("Couldn't access local directory") + .flatten() + .filter(|f| { + f.metadata().unwrap().is_file() + && f.file_name().into_string().unwrap().ends_with(".csv") + }) + .max_by_key(|x| x.metadata().unwrap().modified().unwrap()) + { + let csv_file = std::fs::File::open(last_modified_file.path()).unwrap(); + // Skip first two lines as they're info about system + let mut reader = std::io::BufReader::new(csv_file); + let mut tmp = String::new(); + let _ = reader.read_line(&mut tmp); + let _ = reader.read_line(&mut tmp); + let mut rdr = csv::ReaderBuilder::new().from_reader(reader); + let frame_times = rdr + .records() + .flatten() + .flat_map(|record| record.get(1).unwrap().parse::()) + .collect::>(); + + results.insert( + format!("{key}.frame_time.mean"), + (statistical::mean(&frame_times) * 1000.0) as u64, + ); + results.insert( + format!("{key}.frame_time.median"), + (statistical::median(&frame_times) * 1000.0) as u64, + ); + results.insert( + format!("{key}.frame_time.min"), + frame_times + .iter() + .map(|d| (d * 1000.0) as u64) + .min() + .unwrap(), + ); + results.insert( + format!("{key}.frame_time.max"), + frame_times + .iter() + .map(|d| (d * 1000.0) as u64) + .max() + .unwrap(), + ); + results.insert( + format!("{key}.frame_time.std_dev"), + (statistical::standard_deviation(&frame_times, None) * 1000.0) as u64, + ); + } + results } } diff --git a/src/metrics/stress_tests.rs b/src/metrics/stress_tests.rs index 6c270e92a..0e760e8eb 100644 --- a/src/metrics/stress_tests.rs +++ b/src/metrics/stress_tests.rs @@ -118,9 +118,17 @@ impl Metrics for StressTest { .into_iter() .flat_map(|f| ["--features".to_string(), f]); + let _guard = sh.push_env( + "MANGOHUD_CONFIG", + format!( + "output_folder={},autostart_log=1", + std::env::current_dir().unwrap().display() + ), + ); + let cmd = cmd!( sh, - "xvfb-run cargo run --release {features...} --example {stress_tests} -- {parameters...}" + "xvfb-run mangohud cargo run --release {features...} --example {stress_tests} -- {parameters...}" ); let mut results = HashMap::new(); @@ -260,6 +268,58 @@ impl Metrics for StressTest { results.insert(format!("{key}.duration"), elapsed.as_millis() as u64); results.insert(format!("{key}.frames"), self.nb_frames as u64); + if let Some(last_modified_file) = std::fs::read_dir(".") + .expect("Couldn't access local directory") + .flatten() + .filter(|f| { + f.metadata().unwrap().is_file() + && f.file_name().into_string().unwrap().ends_with(".csv") + }) + .max_by_key(|x| x.metadata().unwrap().modified().unwrap()) + { + let csv_file = std::fs::File::open(last_modified_file.path()).unwrap(); + // Skip first two lines as they're info about system + let mut reader = std::io::BufReader::new(csv_file); + let mut tmp = String::new(); + let _ = reader.read_line(&mut tmp); + let _ = reader.read_line(&mut tmp); + let mut rdr = csv::ReaderBuilder::new().from_reader(reader); + let frame_times = rdr + .records() + .flatten() + .flat_map(|record| record.get(1).unwrap().parse::()) + .collect::>(); + + results.insert( + format!("{key}.frame_time.mean"), + (statistical::mean(&frame_times) * 1000.0) as u64, + ); + results.insert( + format!("{key}.frame_time.median"), + (statistical::median(&frame_times) * 1000.0) as u64, + ); + results.insert( + format!("{key}.frame_time.min"), + frame_times + .iter() + .map(|d| (d * 1000.0) as u64) + .min() + .unwrap(), + ); + results.insert( + format!("{key}.frame_time.max"), + frame_times + .iter() + .map(|d| (d * 1000.0) as u64) + .max() + .unwrap(), + ); + results.insert( + format!("{key}.frame_time.std_dev"), + (statistical::standard_deviation(&frame_times, None) * 1000.0) as u64, + ); + } + results } }