concurrency (broken)

This commit is contained in:
jacekpoz 2024-04-09 17:15:33 +02:00
parent 8e3665ed95
commit 859d6d1d64
Signed by: poz
SSH key fingerprint: SHA256:JyLeVWE4bF3tDnFeUpUaJsPsNlJyBldDGV/dIKSLyN8

View file

@ -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::<u64>()
.expect("k must be u64");
let mut insertion_results_small: HashMap<u64, Vec<SortResult>> = HashMap::new();
let mut quick_results_small: HashMap<u64, Vec<SortResult>> = HashMap::new();
let mut hybrid_results_small: HashMap<u64, Vec<SortResult>> = HashMap::new();
let insertion_results_small: Arc<RwLock<HashMap<u64, Vec<SortResult>>>> = Arc::new(RwLock::new(HashMap::new()));
let quick_results_small: Arc<RwLock<HashMap<u64, Vec<SortResult>>>> = Arc::new(RwLock::new(HashMap::new()));
let hybrid_results_small: Arc<RwLock<HashMap<u64, Vec<SortResult>>>> = 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<RwLock<HashMap<u64, Vec<SortResult>>>> = Arc::new(RwLock::new(HashMap::new()));
let hybrid_results_large: Arc<RwLock<HashMap<u64, Vec<SortResult>>>> = 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<u64, Vec<SortResult>> = HashMap::new();
let mut hybrid_results_large: HashMap<u64, Vec<SortResult>> = 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);