Skip to content

Instantly share code, notes, and snippets.

@MrAlert
Created July 16, 2015 23:51
Show Gist options
  • Save MrAlert/f4317ec44768284670bf to your computer and use it in GitHub Desktop.
Save MrAlert/f4317ec44768284670bf to your computer and use it in GitHub Desktop.
Rust mutex benchmark
// Based on http://preshing.com/20111118/locks-arent-slow-lock-contention-is/
#![feature(const_fn, rand, test)]
extern crate rand;
extern crate test;
use rand::{ChaChaRng, Rng};
use rand::distributions::{Exp, IndependentSample};
use std::cmp::min;
use std::sync::{Arc, Mutex};
use std::thread;
use test::Bencher;
fn mutex_bench(threads: u32, cycle_units: f64, duty_cycle: f64, total_units: u64) {
let thread_units = total_units / threads as u64;
let unlocked_units = cycle_units * (1.0 - duty_cycle);
let locked_units = cycle_units * duty_cycle;
let mutex: Arc<Mutex<u64>> = Arc::new(Mutex::new(0));
let unlocked_dist = Exp::new(1.0 / unlocked_units);
let locked_dist = Exp::new(1.0 / locked_units);
let mut joins = Vec::with_capacity(threads as usize);
for i in 0..threads {
let mutex = mutex.clone();
let join = thread::spawn(move || {
let mut rng = ChaChaRng::new_unseeded();
rng.set_counter(0, i as u64);
let mut units_left = thread_units;
while units_left > 0 {
let units1 = min(unlocked_dist.ind_sample(&mut rng).round() as u64, units_left);
for _ in 0..units1 {
let _: u32 = rng.gen();
}
units_left -= units1;
let mut l = mutex.lock().unwrap();
let units2 = min(locked_dist.ind_sample(&mut rng).round() as u64, units_left);
for _ in 0..units2 {
let _: u32 = rng.gen();
}
units_left -= units2;
*l += units1 + units2;
drop(l);
}
});
joins.push(join);
}
for join in joins {
join.join().unwrap();
}
assert_eq!(*mutex.lock().unwrap(), thread_units * threads as u64);
}
fn main() {}
macro_rules! benchtest {($nm:ident, $th:expr, $cu:expr, $dc:expr, $tu:expr) => (
#[bench]
fn $nm(b: &mut Bencher) {
b.iter(|| mutex_bench($th, $cu, $dc, $tu))
}
)}
benchtest!{mutex_1t_1c_25d, 1, 1.0, 0.25, 1000}
benchtest!{mutex_2t_1c_25d, 2, 1.0, 0.25, 1000}
benchtest!{mutex_3t_1c_25d, 3, 1.0, 0.25, 1000}
benchtest!{mutex_4t_1c_25d, 4, 1.0, 0.25, 1000}
benchtest!{mutex_1t_10c_25d, 1, 10.0, 0.25, 1000}
benchtest!{mutex_2t_10c_25d, 2, 10.0, 0.25, 1000}
benchtest!{mutex_3t_10c_25d, 3, 10.0, 0.25, 1000}
benchtest!{mutex_4t_10c_25d, 4, 10.0, 0.25, 1000}
benchtest!{mutex_1t_100c_25d, 1, 100.0, 0.25, 1000}
benchtest!{mutex_2t_100c_25d, 2, 100.0, 0.25, 1000}
benchtest!{mutex_3t_100c_25d, 3, 100.0, 0.25, 1000}
benchtest!{mutex_4t_100c_25d, 4, 100.0, 0.25, 1000}
benchtest!{mutex_1t_1c_50d, 1, 1.0, 0.50, 1000}
benchtest!{mutex_2t_1c_50d, 2, 1.0, 0.50, 1000}
benchtest!{mutex_3t_1c_50d, 3, 1.0, 0.50, 1000}
benchtest!{mutex_4t_1c_50d, 4, 1.0, 0.50, 1000}
benchtest!{mutex_1t_10c_50d, 1, 10.0, 0.50, 1000}
benchtest!{mutex_2t_10c_50d, 2, 10.0, 0.50, 1000}
benchtest!{mutex_3t_10c_50d, 3, 10.0, 0.50, 1000}
benchtest!{mutex_4t_10c_50d, 4, 10.0, 0.50, 1000}
benchtest!{mutex_1t_100c_50d, 1, 100.0, 0.50, 1000}
benchtest!{mutex_2t_100c_50d, 2, 100.0, 0.50, 1000}
benchtest!{mutex_3t_100c_50d, 3, 100.0, 0.50, 1000}
benchtest!{mutex_4t_100c_50d, 4, 100.0, 0.50, 1000}
benchtest!{mutex_1t_1c_75d, 1, 1.0, 0.75, 1000}
benchtest!{mutex_2t_1c_75d, 2, 1.0, 0.75, 1000}
benchtest!{mutex_3t_1c_75d, 3, 1.0, 0.75, 1000}
benchtest!{mutex_4t_1c_75d, 4, 1.0, 0.75, 1000}
benchtest!{mutex_1t_10c_75d, 1, 10.0, 0.75, 1000}
benchtest!{mutex_2t_10c_75d, 2, 10.0, 0.75, 1000}
benchtest!{mutex_3t_10c_75d, 3, 10.0, 0.75, 1000}
benchtest!{mutex_4t_10c_75d, 4, 10.0, 0.75, 1000}
benchtest!{mutex_1t_100c_75d, 1, 100.0, 0.75, 1000}
benchtest!{mutex_2t_100c_75d, 2, 100.0, 0.75, 1000}
benchtest!{mutex_3t_100c_75d, 3, 100.0, 0.75, 1000}
benchtest!{mutex_4t_100c_75d, 4, 100.0, 0.75, 1000}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment