Skip to content

Instantly share code, notes, and snippets.

@TheIronBorn
Last active May 31, 2022 21:19
Show Gist options
  • Save TheIronBorn/ba1f1e39b6466353b1eee6cf450fe247 to your computer and use it in GitHub Desktop.
Save TheIronBorn/ba1f1e39b6466353b1eee6cf450fe247 to your computer and use it in GitHub Desktop.
Benchmarking Monte Carlo estimation of pi, using my SIMD branch of the rand crate https://github.com/TheIronBorn/rand/tree/simd
#![feature(test)]
#![feature(stdsimd)]
extern crate rand;
extern crate test;
use std::simd::*;
use std::mem;
use test::black_box;
use rand::NewRng;
use rand::distributions::{Distribution, Range};
const BENCH_N: u64 = 1 << 1;
#[bench]
fn scalar(b: &mut test::Bencher) {
b.iter(|| {
for _ in 0..BENCH_N {
let range = Range::new(-1.0f64, 1.0);
let mut rng = rand::prng::XorShiftRng::new();
let total = 1_000_000;
let mut in_circle = 0;
for _ in 0..total {
let a = range.sample(&mut rng);
let b = range.sample(&mut rng);
if a*a + b*b <= 1.0 {
in_circle += 1;
}
}
black_box(in_circle as f64);
}
});
b.bytes = mem::size_of::<f64>() as u64 * 1_000_000 * BENCH_N;
}
#[bench]
fn simd(b: &mut test::Bencher) {
b.iter(|| {
for _ in 0..BENCH_N {
let range = Range::new(f64x4::splat(-1.0), f64x4::splat(1.0));
let mut rng = rand::prng::Sfc32x4Rng::new();
let total = 1_000_000;
let mut in_circle = u64x4::splat(0);
for _ in 0..total {
let a = range.sample(&mut rng);
let b = range.sample(&mut rng);
let in_circle_mask = (a*a + b*b).le(f64x4::splat(1.0));
// in_circle += is_in_circle { 1 } else { 0 };
in_circle += in_circle_mask.select(u64x4::splat(1), u64x4::splat(0));
}
black_box(in_circle.wrapping_sum() as f64);
}
});
b.bytes = mem::size_of::<f64x4>() as u64 * 1_000_000 * BENCH_N;
}
/* with a Sandy Bridge cpu
test scalar ... bench: 26,424,886 ns/iter (+/- 10,327,348) = 605 MB/s
test simd ... bench: 28,363,059 ns/iter (+/- 48,045,043) = 2256 MB/s
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment