diff --git a/Cargo.toml b/Cargo.toml index c989cad..ebb0e6d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,8 +3,7 @@ members = [ "blackheap", "blackheap-benchmarker", - "blackheap-core", - "blackheap-analyzer" + "blackheap-core" ] resolver = "2" diff --git a/blackheap-analyzer/Cargo.toml b/blackheap-analyzer/Cargo.toml deleted file mode 100644 index 5c4100d..0000000 --- a/blackheap-analyzer/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "blackheap-analyzer" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] diff --git a/blackheap-analyzer/src/lib.rs b/blackheap-analyzer/src/lib.rs deleted file mode 100644 index 7d12d9a..0000000 --- a/blackheap-analyzer/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} diff --git a/blackheap/Cargo.toml b/blackheap/Cargo.toml index 56324b5..cdfbc12 100644 --- a/blackheap/Cargo.toml +++ b/blackheap/Cargo.toml @@ -10,7 +10,6 @@ authors = ["Lars Quentin "] readme = "./README.md" [dependencies] -blackheap-analyzer = { path = "../blackheap-analyzer" } blackheap-benchmarker = { path = "../blackheap-benchmarker" } blackheap-core = { path = "../blackheap-core" } clap = { version = "4.5", features = ["derive"] } diff --git a/blackheap/src/assets/progress.rs b/blackheap/src/assets/progress.rs index adfeaca..c1320f1 100644 --- a/blackheap/src/assets/progress.rs +++ b/blackheap/src/assets/progress.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use std::{collections::HashMap, fs}; use thiserror::Error; -use crate::{Benchmark, BenchmarkScenario}; +use crate::benchmark::{Benchmark, BenchmarkScenario}; const VERSION_NUMBER: u32 = 1; pub const FILE_NAME: &str = "BlackheapProgress.toml"; diff --git a/blackheap/src/benchmark.rs b/blackheap/src/benchmark.rs new file mode 100644 index 0000000..f037f45 --- /dev/null +++ b/blackheap/src/benchmark.rs @@ -0,0 +1,172 @@ +use crate::assets::progress::Operation; +use crate::assets::progress::{BenchmarkProgressToml, ProgressError, FILE_NAME}; +use crate::cli::Cli; +use blackheap_benchmarker::{AccessPattern, BenchmarkConfig, BenchmarkResults}; +use serde::{Deserialize, Serialize}; +use std::{ + collections::HashMap, + fs, + path::{Path, PathBuf}, +}; +use tracing::info; + +const ACCESS_SIZES: [u32; 24] = [ + 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, + 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, +]; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum BenchmarkScenario { + RandomUncached, + SameOffset, +} + +impl ToString for BenchmarkScenario { + fn to_string(&self) -> String { + match self { + BenchmarkScenario::SameOffset => "SameOffset".to_string(), + BenchmarkScenario::RandomUncached => "RandomUncached".to_string(), + } + } +} + +#[derive(Debug, Clone)] +pub struct Benchmark { + pub scenario: BenchmarkScenario, + pub config: BenchmarkConfig, + pub results: HashMap>, +} + +impl Benchmark { + pub fn get_all_benchmarks(root: bool, file_path: &str) -> Vec { + vec![ + Self::new_random_uncached_read(file_path, root), + Self::new_random_uncached_write(file_path, root), + Self::new_same_offset_read(file_path), + Self::new_same_offset_write(file_path), + ] + } + + pub fn new_random_uncached_read(file_path: &str, root: bool) -> Self { + Benchmark { + scenario: BenchmarkScenario::RandomUncached, + config: BenchmarkConfig { + filepath: file_path.to_string(), + memory_buffer_in_bytes: 4 * 1024 * 1024 * 1024, + file_size_in_bytes: 25 * 1024 * 1024 * 1024, + access_size_in_bytes: 4 * 1024, /* any random value */ + number_of_io_op_tests: 1000, + access_pattern_in_memory: AccessPattern::Random, + access_pattern_in_file: AccessPattern::Random, + is_read_operation: true, + prepare_file_size: true, + drop_cache_first: root, + do_reread: false, + restrict_free_ram_to: None, + }, + results: HashMap::new(), + } + } + + pub fn new_random_uncached_write(file_path: &str, root: bool) -> Self { + Benchmark { + scenario: BenchmarkScenario::RandomUncached, + config: { + let mut config = Self::new_random_uncached_read(file_path, root).config; + config.is_read_operation = false; + config + }, + results: HashMap::new(), + } + } + + pub fn new_same_offset_read(file_path: &str) -> Self { + Benchmark { + scenario: BenchmarkScenario::SameOffset, + config: BenchmarkConfig { + filepath: file_path.to_string(), + memory_buffer_in_bytes: 4 * 1024 * 1024 * 1024, + file_size_in_bytes: 25 * 1024 * 1024 * 1024, + access_size_in_bytes: 4 * 1024, /* any random value */ + number_of_io_op_tests: 1000, + access_pattern_in_memory: AccessPattern::Const, + access_pattern_in_file: AccessPattern::Const, + is_read_operation: true, + prepare_file_size: true, + drop_cache_first: false, + do_reread: true, + restrict_free_ram_to: None, + }, + results: HashMap::new(), + } + } + + pub fn new_same_offset_write(file_path: &str) -> Self { + Benchmark { + scenario: BenchmarkScenario::SameOffset, + config: { + let mut config = Self::new_same_offset_read(file_path).config; + config.is_read_operation = false; + config + }, + results: HashMap::new(), + } + } +} + +pub fn load_or_create_progress( + directory_path: &Path, + benchmarks: &[Benchmark], +) -> Result { + let mut full_path = PathBuf::from(directory_path); + full_path.push(FILE_NAME); + + /* If it does not exist, create a new one based on our benchmarks */ + if !full_path.exists() { + info!("No previous results were found. Creating new ones"); + let toml = BenchmarkProgressToml::new_from_benchmarks(benchmarks, &ACCESS_SIZES); + toml.to_file(full_path.to_str().unwrap())?; + return Ok(toml); + } + + /* If it does exist, try to parse it */ + let toml = BenchmarkProgressToml::from_file(full_path.to_str().unwrap())?; + info!("Previous results loaded"); + Ok(toml) +} + +pub fn save_and_update_progress( + b: &Benchmark, + access_size: u32, + results: &BenchmarkResults, + cli: &Cli, + progress: &mut BenchmarkProgressToml, +) -> Result<(), ProgressError> { + let operation = Operation::from_is_read_op(b.config.is_read_operation).to_string(); + let file_path = format!( + "{}/{}/{}/{}.txt", + cli.to.to_str().unwrap(), + b.scenario.to_string(), + operation, + access_size + ); + + /* we save it as newline seperated f64s */ + let durations_str = results + .durations + .iter() + .map(|d| d.to_string()) + .collect::>() + .join("\n"); + + /* save the file */ + fs::write(&file_path, &durations_str)?; + + /* Update the progress */ + progress.update_access_sizes_done(b, access_size); + + let progress_file_path = format!("{}/{}", cli.to.to_str().unwrap(), &FILE_NAME); + progress.to_file(&progress_file_path)?; + + Ok(()) +} diff --git a/blackheap/src/main.rs b/blackheap/src/main.rs index 6060808..965a3f3 100644 --- a/blackheap/src/main.rs +++ b/blackheap/src/main.rs @@ -1,182 +1,14 @@ -use std::{ - collections::HashMap, - fs, io, - path::{Path, PathBuf}, -}; - use crate::{assets::progress::Operation, cli::Cli}; -use assets::progress::{BenchmarkProgressToml, ProgressError, FILE_NAME}; -use blackheap_benchmarker::{AccessPattern, BenchmarkConfig, BenchmarkResults, ErrorCodes}; +use benchmark::Benchmark; +use blackheap_benchmarker::ErrorCodes; use clap::Parser; -use serde::{Deserialize, Serialize}; use tracing::{debug, error, info}; -use tracing_subscriber::fmt::layer; mod assets; +mod benchmark; mod cli; -const ACCESS_SIZES: [u32; 24] = [ - 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, - 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, -]; - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub enum BenchmarkScenario { - RandomUncached, - SameOffset, -} - -impl ToString for BenchmarkScenario { - fn to_string(&self) -> String { - match self { - BenchmarkScenario::SameOffset => "SameOffset".to_string(), - BenchmarkScenario::RandomUncached => "RandomUncached".to_string(), - } - } -} - -#[derive(Debug, Clone)] -struct Benchmark { - scenario: BenchmarkScenario, - config: BenchmarkConfig, - results: HashMap>, -} - -impl Benchmark { - pub fn get_all_benchmarks(root: bool, file_path: &str) -> Vec { - vec![ - Self::new_random_uncached_read(file_path, root), - Self::new_random_uncached_write(file_path, root), - Self::new_same_offset_read(file_path), - Self::new_same_offset_write(file_path), - ] - } - - pub fn new_random_uncached_read(file_path: &str, root: bool) -> Self { - Benchmark { - scenario: BenchmarkScenario::RandomUncached, - config: BenchmarkConfig { - filepath: file_path.to_string(), - memory_buffer_in_bytes: 4 * 1024 * 1024 * 1024, - file_size_in_bytes: 25 * 1024 * 1024 * 1024, - access_size_in_bytes: 4 * 1024, /* any random value */ - number_of_io_op_tests: 1000, - access_pattern_in_memory: AccessPattern::Random, - access_pattern_in_file: AccessPattern::Random, - is_read_operation: true, - prepare_file_size: true, - drop_cache_first: root, - do_reread: false, - restrict_free_ram_to: None, - }, - results: HashMap::new(), - } - } - - pub fn new_random_uncached_write(file_path: &str, root: bool) -> Self { - Benchmark { - scenario: BenchmarkScenario::RandomUncached, - config: { - let mut config = Self::new_random_uncached_read(file_path, root).config; - config.is_read_operation = false; - config - }, - results: HashMap::new(), - } - } - - pub fn new_same_offset_read(file_path: &str) -> Self { - Benchmark { - scenario: BenchmarkScenario::SameOffset, - config: BenchmarkConfig { - filepath: file_path.to_string(), - memory_buffer_in_bytes: 4 * 1024 * 1024 * 1024, - file_size_in_bytes: 25 * 1024 * 1024 * 1024, - access_size_in_bytes: 4 * 1024, /* any random value */ - number_of_io_op_tests: 1000, - access_pattern_in_memory: AccessPattern::Const, - access_pattern_in_file: AccessPattern::Const, - is_read_operation: true, - prepare_file_size: true, - drop_cache_first: false, - do_reread: true, - restrict_free_ram_to: None, - }, - results: HashMap::new(), - } - } - - pub fn new_same_offset_write(file_path: &str) -> Self { - Benchmark { - scenario: BenchmarkScenario::SameOffset, - config: { - let mut config = Self::new_same_offset_read(file_path).config; - config.is_read_operation = false; - config - }, - results: HashMap::new(), - } - } -} - -fn load_or_create_progress( - directory_path: &Path, - benchmarks: &[Benchmark], -) -> Result { - let mut full_path = PathBuf::from(directory_path); - full_path.push(FILE_NAME); - - /* If it does not exist, create a new one based on our benchmarks */ - if !full_path.exists() { - info!("No previous results were found. Creating new ones"); - let toml = BenchmarkProgressToml::new_from_benchmarks(benchmarks, &ACCESS_SIZES); - toml.to_file(full_path.to_str().unwrap())?; - return Ok(toml); - } - - /* If it does exist, try to parse it */ - let toml = BenchmarkProgressToml::from_file(full_path.to_str().unwrap())?; - info!("Previous results loaded"); - Ok(toml) -} - -fn save_and_update_progress( - b: &Benchmark, - access_size: u32, - results: &BenchmarkResults, - cli: &Cli, - progress: &mut BenchmarkProgressToml, -) -> Result<(), ProgressError> { - let operation = Operation::from_is_read_op(b.config.is_read_operation).to_string(); - let file_path = format!( - "{}/{}/{}/{}.txt", - cli.to.to_str().unwrap(), - b.scenario.to_string(), - operation, - access_size - ); - - /* we save it as newline seperated f64s */ - let durations_str = results - .durations - .iter() - .map(|d| d.to_string()) - .collect::>() - .join("\n"); - - /* save the file */ - fs::write(&file_path, &durations_str)?; - - /* Update the progress */ - progress.update_access_sizes_done(b, access_size); - - let progress_file_path = format!("{}/{}", cli.to.to_str().unwrap(), &FILE_NAME); - progress.to_file(&progress_file_path)?; - - Ok(()) -} - fn main() { /* Init boilerplate */ human_panic::setup_panic!(); @@ -194,7 +26,7 @@ fn main() { /* Load previous results */ info!("Trying to load previous results"); let benchmarks = Benchmark::get_all_benchmarks(cli.drop_caches, cli.file.to_str().unwrap()); - let progress = load_or_create_progress(&cli.to, &benchmarks); + let progress = benchmark::load_or_create_progress(&cli.to, &benchmarks); if let Err(e) = progress { error!("{:?}", e); std::process::exit(1); @@ -252,7 +84,8 @@ fn main() { /* Save the result; update and save the progress struct */ info!("Saving the results"); - let res = save_and_update_progress(&b, access_size, &results, &cli, &mut progress); + let res = + benchmark::save_and_update_progress(&b, access_size, &results, &cli, &mut progress); if let Err(e) = res { error!("{:?}", e); std::process::exit(1);