diff --git a/lab3/zad2/.gitignore b/lab3/zad2/.gitignore new file mode 100644 index 0000000..a9bbb74 --- /dev/null +++ b/lab3/zad2/.gitignore @@ -0,0 +1,2 @@ +target/ +results/ diff --git a/lab3/zad2/Cargo.lock b/lab3/zad2/Cargo.lock new file mode 100644 index 0000000..67bf7b2 --- /dev/null +++ b/lab3/zad2/Cargo.lock @@ -0,0 +1,147 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "either" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" + +[[package]] +name = "getrandom" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libgen" +version = "0.1.0" +dependencies = [ + "rand", +] + +[[package]] +name = "libselect" +version = "0.1.0" +dependencies = [ + "libsort", + "rand", +] + +[[package]] +name = "libsort" +version = "0.1.0" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "zad4" +version = "0.1.0" +dependencies = [ + "libgen", + "libselect", + "rayon", +] diff --git a/lab3/zad2/Cargo.toml b/lab3/zad2/Cargo.toml new file mode 100644 index 0000000..43f0cf5 --- /dev/null +++ b/lab3/zad2/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "zad4" +version = "0.1.0" +edition = "2021" + +[dependencies] +libgen = { path = "../../libgen" } +libselect = { path = "../../libselect" } +rayon = "1.10.0" diff --git a/lab3/zad2/src/main.rs b/lab3/zad2/src/main.rs new file mode 100644 index 0000000..7fb411d --- /dev/null +++ b/lab3/zad2/src/main.rs @@ -0,0 +1,116 @@ +use std::{collections::HashMap, env::args, fs::{self, OpenOptions}, io::{self, Write}, sync::{Arc, RwLock}, thread, time::Duration}; + +use libgen::gen_rand; +use libselect::{normal_select::NormalSelect, randomized_select::RandomizedSelect, Select}; + +fn comp_avg(results_map: &HashMap>) -> HashMap { + results_map.iter() + .map(|(i, results)| + (*i, (results.iter() + .map(|res| res.0) + .sum::() as f64 / results.len() as f64))) + .collect() +} + +fn swap_avg(results_map: &HashMap>) -> HashMap { + results_map.iter() + .map(|(i, results)| + (*i, (results.iter() + .map(|res| res.1) + .sum::() as f64 / results.len() as f64))) + .collect() +} + +fn main() -> io::Result<()> { + + let k = args().nth(1) + .expect(format!("usage: {} ", args().nth(0).unwrap()).as_str()) + .parse::() + .expect("k must be usize"); + + let m = 50; + + let normal_results: Arc>>> = Arc::new(RwLock::new(HashMap::new())); + let randomized_results: Arc>>> = Arc::new(RwLock::new(HashMap::new())); + + let mut thread_handles = vec![]; + + let num_cpus = thread::available_parallelism()?.get(); + + let num_cpus = num_cpus - 4; + + for cpu in 0..num_cpus { + let cpu = cpu.clone(); + + let normal_results = Arc::clone(&normal_results); + let randomized_results = Arc::clone(&randomized_results); + let handle = thread::spawn(move || { + for n in ((100 + cpu * 100) as u64..=50000 as u64).step_by(100 * num_cpus) { + if normal_results.read().expect("can't read insertion results small map").get(&(n as u64)).is_some() { + continue; + } + let mut nr = normal_results.write().expect("can't write to insertion results small"); + if randomized_results.read().expect("can't read quick results small map").get(&(n as u64)).is_some() { + continue; + } + let mut rr = randomized_results.write().expect("can't write to quick results small"); + println!("cpu {cpu}: {n}"); + let input = gen_rand(n); + + nr.insert(n, vec![]); + rr.insert(n, vec![]); + + let mut normal = NormalSelect::new(false); + let mut randomized = RandomizedSelect::new(false); + for i in 0..m { + print!("{i} "); + _ = std::io::stdout().flush(); + normal.select(&input, k); + randomized.select(&input, k); + nr.get_mut(&n).unwrap().push((normal.num_comp(), normal.num_swap())); + rr.get_mut(&n).unwrap().push((randomized.num_comp(), randomized.num_swap())); + } + println!(); + } + }); + + thread_handles.push(handle); + } + + for handle in thread_handles { + handle.join().expect("couldn't join handle"); + } + + let normal_results = normal_results.read().expect("can't access results"); + let randomized_results = randomized_results.read().expect("can't access results"); + + let normal_comp_averages = comp_avg(&normal_results); + + let normal_swap_averages = swap_avg(&normal_results); + + let randomized_comp_averages = comp_avg(&randomized_results); + + let randomized_swap_averages = swap_avg(&randomized_results); + + _ = fs::create_dir_all("./results"); + + let mut results_file = OpenOptions::new() + .create(true) + .append(true) + .open(format!("./results/k{k}"))?; + + for n in (100..=50000).step_by(100) { + writeln!(results_file, "{n} {} {} {} {} {} {} {} {}", + normal_comp_averages[&n], + normal_swap_averages[&n], + randomized_comp_averages[&n], + randomized_swap_averages[&n], + normal_comp_averages[&n] / n as f64, + normal_swap_averages[&n] / n as f64, + randomized_comp_averages[&n] / n as f64, + randomized_swap_averages[&n] / n as f64, + )?; + } + + Ok(()) +}