diff --git a/lab2/zad2/src/main.rs b/lab2/zad2/src/main.rs index 1b0628b..acd039e 100644 --- a/lab2/zad2/src/main.rs +++ b/lab2/zad2/src/main.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, env::args, fs::{self, OpenOptions}}; +use std::{collections::HashMap, env::args, fs::{self, OpenOptions}, sync::{Arc, RwLock}, thread}; use std::io::{self, Write}; use libgen::gen_rand; @@ -28,33 +28,89 @@ fn main() -> io::Result<()> { .parse::() .expect("k must be u64"); - let mut insertion_results_small: HashMap> = HashMap::new(); - let mut quick_results_small: HashMap> = HashMap::new(); - let mut hybrid_results_small: HashMap> = HashMap::new(); + let insertion_results_small: Arc>>> = Arc::new(RwLock::new(HashMap::new())); + let quick_results_small: Arc>>> = Arc::new(RwLock::new(HashMap::new())); + let hybrid_results_small: Arc>>> = Arc::new(RwLock::new(HashMap::new())); - for n in (10..=50).step_by(10) { - insertion_results_small.insert(n, vec![]); - quick_results_small.insert(n, vec![]); - hybrid_results_small.insert(n, vec![]); - for _ in 0..k { - insertion_results_small.get_mut(&n).unwrap().push(insertion_sort(&mut gen_rand(n), false)); - quick_results_small.get_mut(&n).unwrap().push(quick_sort(&mut gen_rand(n), false)); - hybrid_results_small.get_mut(&n).unwrap().push(hybrid_sort(&mut gen_rand(n), 8, false)); - } + let quick_results_large: Arc>>> = Arc::new(RwLock::new(HashMap::new())); + let hybrid_results_large: Arc>>> = Arc::new(RwLock::new(HashMap::new())); + + let mut thread_handles = vec![]; + + let num_cpus = thread::available_parallelism()?.get(); + + for cpu in 0..num_cpus { + let cpu = cpu.clone(); + + let insertion_results_small = Arc::clone(&insertion_results_small); + let quick_results_small = Arc::clone(&quick_results_small); + let hybrid_results_small = Arc::clone(&hybrid_results_small); + let handle_small = thread::spawn(move || { + for n in ((10 + cpu * 10)..=50).step_by(10 * num_cpus) { + if insertion_results_small.read().expect("can't read insertion results small map").get(&(n as u64)).is_some() { + continue; + } + let mut irs = insertion_results_small.write().expect("can't write to insertion results small"); + if quick_results_small.read().expect("can't read quick results small map").get(&(n as u64)).is_some() { + continue; + } + let mut qrs = quick_results_small.write().expect("can't write to quick results small"); + if hybrid_results_small.read().expect("can't read hybrid results small map").get(&(n as u64)).is_some() { + continue; + } + let mut hrs = hybrid_results_small.write().expect("can't write to hybrid results small"); + println!("cpu {cpu}: {n}"); + + irs.insert(n as u64, vec![]); + qrs.insert(n as u64, vec![]); + hrs.insert(n as u64, vec![]); + for _ in 0..k { + irs.get_mut(&(n as u64)).unwrap().push(insertion_sort(&mut gen_rand(n as u64), false)); + qrs.get_mut(&(n as u64)).unwrap().push(quick_sort(&mut gen_rand(n as u64), false)); + hrs.get_mut(&(n as u64)).unwrap().push(hybrid_sort(&mut gen_rand(n as u64), 8, false)); + } + } + }); + + thread_handles.push(handle_small); + + let quick_results_large = Arc::clone(&quick_results_large); + let hybrid_results_large = Arc::clone(&hybrid_results_large); + let handle_large = thread::spawn(move || { + for n in ((1000 + cpu * 1000)..=50000).step_by(1000 * num_cpus) { + if quick_results_large.read().expect("can't read quick results large map").get(&(n as u64)).is_some() { + continue; + } + let mut qrl = quick_results_large.write().expect("can't write to quick results large"); + if hybrid_results_large.read().expect("can't read hybrid results large map").get(&(n as u64)).is_some() { + continue; + } + let mut hrl = hybrid_results_large.write().expect("can't write to hybrid results large"); + println!("cpu {cpu}: {n}"); + + qrl.insert(n as u64, vec![]); + hrl.insert(n as u64, vec![]); + for _ in 0..k { + qrl.get_mut(&(n as u64)).unwrap().push(quick_sort(&mut gen_rand(n as u64), false)); + hrl.get_mut(&(n as u64)).unwrap().push(hybrid_sort(&mut gen_rand(n as u64), 8, false)); + } + } + }); + + thread_handles.push(handle_large); } - let mut quick_results_large: HashMap> = HashMap::new(); - let mut hybrid_results_large: HashMap> = HashMap::new(); - - for n in (1000..=50000).step_by(1000) { - quick_results_large.insert(n, vec![]); - hybrid_results_large.insert(n, vec![]); - for _ in 0..k { - quick_results_large.get_mut(&n).unwrap().push(quick_sort(&mut gen_rand(n), false)); - hybrid_results_large.get_mut(&n).unwrap().push(hybrid_sort(&mut gen_rand(n), 8, false)); - } + for handle in thread_handles { + handle.join().expect("couldn't join handle"); } + let insertion_results_small = insertion_results_small.read().expect("can't access results"); + let quick_results_small = quick_results_small.read().expect("can't access results"); + let hybrid_results_small = hybrid_results_small.read().expect("can't access results"); + + let quick_results_large = quick_results_large.read().expect("can't access results"); + let hybrid_results_large = hybrid_results_large.read().expect("can't access results"); + let insertion_comp_averages_small = comp_avg(&insertion_results_small); let insertion_swap_averages_small = swap_avg(&insertion_results_small);