From c732864a741f2474e79d315cc3f5e835379051f2 Mon Sep 17 00:00:00 2001 From: teridax Date: Wed, 31 May 2023 09:00:49 +0200 Subject: [PATCH] added benchmark for `threadpool` using `criterion`. --- .gitignore | 1 + Cargo.toml | 7 ++++ benches/multithreading.rs | 74 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 benches/multithreading.rs diff --git a/.gitignore b/.gitignore index 4c790d0..98f2979 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target /Cargo.lock .DS_Store +/.vscode \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index a6d8ad6..69cd0ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,10 @@ authors = ["Sven Vogel", "Felix L. Müller", "Elias Alexander", "Elias Schmidt"] png = "0.17.8" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" + +[dev-dependencies] +criterion = "0.5.1" + +[[bench]] +name = "multithreading" +harness = false \ No newline at end of file diff --git a/benches/multithreading.rs b/benches/multithreading.rs new file mode 100644 index 0000000..ffd36d8 --- /dev/null +++ b/benches/multithreading.rs @@ -0,0 +1,74 @@ +use std::sync::Arc; + +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use imsearch::multithreading::ThreadPool; + +fn dot(a: &[f64], b: &[f64]) -> f64 { + let mut sum = 0.0; + + for i in 0..a.len() { + sum += a[i] * b[i]; + } + + sum +} + +fn bench_single_threaded(a: &Vec, b: &Vec) { + black_box(dot(a, b)); +} + +fn bench_threadpool(a: Arc>, b: Arc>) { + let mut pool = ThreadPool::new(); + + const CHUNKS: usize = 100; + + let steps = a.len() / CHUNKS; + + for i in 0..CHUNKS { + let chunk = i * steps; + let aa = a.clone(); + let bb = b.clone(); + pool.enqueue(move || { + let a = &aa[chunk..(chunk + steps)]; + let b = &bb[chunk..(chunk + steps)]; + dot(a, b) + }); + } + + black_box( + pool.join_all() + .into_iter() + .map(|r| r.unwrap()) + .reduce(|a, b| a + b), + ); +} + +#[inline] +fn hash(x: f64) -> f64 { + ((x * 234.8743 + 3.8274).sin() * 87624.58376).fract() +} + +fn create_vec(size: usize) -> Arc> { + let mut vec = Vec::with_capacity(size); + + for i in 0..size { + vec.push(hash(i as f64)); + } + + Arc::new(vec) +} + +pub fn benchmark_threadpool(c: &mut Criterion) { + let vec_a = create_vec(1_000_000); + let vec_b = create_vec(1_000_000); + + c.bench_function("single threaded", |b| { + b.iter(|| bench_single_threaded(&vec_a, &vec_b)) + }); + c.bench_function("multi threaded", |b| { + b.iter(|| bench_threadpool(vec_a.clone(), vec_b.clone())) + }); +} + +criterion_group!(benches, benchmark_threadpool); +criterion_main!(benches);