Advertisement
NLinker

parallel sum vs sequential sum

Nov 4th, 2019
552
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 1.92 KB | None | 0 0
  1. // cargo bench
  2.  
  3. use rand::distributions::{Distribution, Uniform};
  4. use crossbeam;
  5. const NTHREADS: usize = 8;
  6.  
  7. fn random_vec(length: usize) -> Vec<i32> {
  8.     let step = Uniform::new_inclusive(1, 100);
  9.     let mut rng = rand::thread_rng();
  10.     step.sample_iter(&mut rng).take(length).collect()
  11. }
  12.  
  13. fn main() {
  14.     let numbers = random_vec(1_000);
  15.     println!("global sum via threads    : {}", parallel_sum(&numbers));
  16.     println!("global sum single-threaded: {}", sequential_sum(&numbers));
  17. }
  18.  
  19. fn parallel_sum(numbers: &[i32]) -> i32 {
  20.     let num_tasks_per_thread = numbers.len() / NTHREADS;
  21.     crossbeam::scope(|scope| {
  22.         // The `collect` is important to eagerly start the threads!
  23.         let threads: Vec<_> = numbers
  24.             .chunks(num_tasks_per_thread)
  25.             .map(|chunk| scope.spawn(move |_| chunk.iter().cloned().sum::<i32>()))
  26.             .collect();
  27.  
  28.         let thread_sum: i32 = threads.into_iter().map(|t| t.join().unwrap()).sum();
  29.         return thread_sum;
  30.     }).unwrap()
  31. }
  32.  
  33. fn sequential_sum(numbers: &[i32]) -> i32 {
  34.     let num_tasks_per_thread = numbers.len() / NTHREADS;
  35.     crossbeam::scope(|scope| {
  36.         // The `collect` is important to eagerly start the threads!
  37.         let _threads: Vec<_> = numbers
  38.             .chunks(num_tasks_per_thread)
  39.             .map(|chunk| scope.spawn(move |_| chunk.iter().cloned().sum::<i32>()))
  40.             .collect();
  41.  
  42.         let no_thread_sum: i32 = numbers.iter().cloned().sum();
  43.         return no_thread_sum;
  44.     }).unwrap()
  45. }
  46.  
  47. #[cfg(test)]
  48. mod tests {
  49.     extern crate test;
  50.     use super::*;
  51.     use test::Bencher;
  52.  
  53.     #[bench]
  54.     fn bench_sequential(b: &mut Bencher) {
  55.         let numbers = random_vec(10_000_000);
  56.         b.iter(|| sequential_sum(&numbers));
  57.     }
  58.  
  59.     #[bench]
  60.     fn bench_parallel(b: &mut Bencher) {
  61.         let numbers = random_vec(10_000_000);
  62.         b.iter(|| parallel_sum(&numbers));
  63.     }
  64. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement