diff --git a/Cargo.lock b/Cargo.lock index 714ec9e..16f2d71 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,6 +22,8 @@ version = "0.1.0" dependencies = [ "benchlib-rs", "crossbeam-channel", + "crossbeam-utils", + "num_cpus", "rayon", ] diff --git a/Cargo.toml b/Cargo.toml index 576c0ff..452fe08 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,3 +13,5 @@ opt-level = 1 rayon = "1.3.0" crossbeam-channel = "0.4.2" benchlib-rs = "0.2.2" +crossbeam-utils = "0.7.2" +num_cpus = "1.0" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 6544b6e..1efffaa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,16 +7,25 @@ use benchlib::benching::Bencher; pub fn main() { let mut bencher = Bencher::new(); bencher - .set_iterations(1000000) + .set_iterations(10000) .print_settings() .bench("Dry Run", || {}) .bench("Multiply to 100", || to_bench::multiply_to(100)) .bench("Summation from 0u128 to 1000", || { - to_bench::summation_to_1000() + to_bench::summation_to(1000) }) + .bench( + "Parallel summation with arc mutex from 0u128 to 1000", + || to_bench::summation_using_mutex(1000), + ) + .compare() .set_iterations(1000) .print_settings() - .bench("Spawn and Stop thread", || to_bench::start_stop_thread()) + .bench("Spawn and stop thread", || to_bench::start_stop_thread()) + .bench("Start and stop threads==cpus", || { + to_bench::start_and_wait_for_num_cpu_threads() + }) + .compare() .bench("MPSC channel transmit 1000x u128", || { to_bench::send_mpsc_channel() }) @@ -32,3 +41,18 @@ pub fn main() { }) .compare(); } + +#[cfg(test)] +pub mod test { + use crate::to_bench::{largest_prime, largest_prime_par, summation_to, summation_using_mutex}; + + #[test] + pub fn summation_works() { + assert_eq!(summation_to(1000), summation_using_mutex(1000)) + } + + #[test] + pub fn primes_work() { + assert_eq!(largest_prime(10000), largest_prime_par(10000)) + } +} diff --git a/src/to_bench.rs b/src/to_bench.rs index 04dd34b..58b9c1f 100644 --- a/src/to_bench.rs +++ b/src/to_bench.rs @@ -1,6 +1,9 @@ use crossbeam_channel::unbounded; +use crossbeam_utils::sync::WaitGroup; +use num_cpus; use rayon::prelude::*; use std::sync::mpsc::channel; +use std::sync::{Arc, Mutex}; use std::thread; pub fn start_stop_thread() { @@ -10,9 +13,9 @@ pub fn start_stop_thread() { handle.join().unwrap(); } -pub fn summation_to_1000() -> u128 { +pub fn summation_to(end: u128) -> u128 { let mut res = 0u128; - for i in 0u128..1000 { + for i in 0u128..end { res += i; } res @@ -82,3 +85,36 @@ pub fn send_mpmc_channel() { std::mem::drop(rx); handle.join().unwrap(); } + +pub fn summation_using_mutex(end: usize) -> u128 { + let wg = WaitGroup::new(); + let num = Arc::new(Mutex::new(0u128)); + + for thread_number in 0..num_cpus::get() { + let wg = wg.clone(); + let num = Arc::clone(&num); + thread::spawn(move || { + for i in (thread_number..end).step_by(num_cpus::get()) { + *num.lock().unwrap() += i as u128; + } + std::mem::drop(wg); + }); + } + wg.wait(); + let result = *num.lock().unwrap(); + + result +} + +pub fn start_and_wait_for_num_cpu_threads() { + let wg = WaitGroup::new(); + + for thread_number in 0..num_cpus::get() { + let wg = wg.clone(); + thread::spawn(move || { + std::mem::drop(wg); + thread_number + }); + } + wg.wait(); +}