Start switching benchmarks to criterion.

This commit is contained in:
sebcrozet 2019-03-23 18:01:04 +01:00
parent 3cbe60523a
commit 6d76249d74
6 changed files with 54 additions and 49 deletions

View File

@ -51,9 +51,18 @@ pest_derive = { version = "2.0", optional = true }
[dev-dependencies] [dev-dependencies]
serde_json = "1.0" serde_json = "1.0"
rand_xorshift = "0.1" rand_xorshift = "0.1"
criterion = "0.2"
[workspace] [workspace]
members = [ "nalgebra-lapack", "nalgebra-glm" ] members = [ "nalgebra-lapack", "nalgebra-glm" ]
[[bench]]
name = "nalgebra_bench"
harness = false
path = "benches/lib.rs"
[patch.crates-io] [patch.crates-io]
alga = { path = "../alga/alga" } alga = { path = "../alga/alga" }
[profile.bench]
lto = true

View File

@ -2,56 +2,52 @@
macro_rules! bench_binop( macro_rules! bench_binop(
($name: ident, $t1: ty, $t2: ty, $binop: ident) => { ($name: ident, $t1: ty, $t2: ty, $binop: ident) => {
#[bench] fn $name(bh: &mut criterion::Criterion) {
fn $name(bh: &mut Bencher) {
use rand::SeedableRng; use rand::SeedableRng;
let mut rng = IsaacRng::seed_from_u64(0); let mut rng = IsaacRng::seed_from_u64(0);
let a = rng.gen::<$t1>(); let a = rng.gen::<$t1>();
let b = rng.gen::<$t2>(); let b = rng.gen::<$t2>();
bh.iter(|| { bh.bench_function(stringify!($name), move |bh| bh.iter(|| {
a.$binop(b) a.$binop(b)
}) }));
} }
} }
); );
macro_rules! bench_binop_ref( macro_rules! bench_binop_ref(
($name: ident, $t1: ty, $t2: ty, $binop: ident) => { ($name: ident, $t1: ty, $t2: ty, $binop: ident) => {
#[bench] fn $name(bh: &mut criterion::Criterion) {
fn $name(bh: &mut Bencher) {
use rand::SeedableRng; use rand::SeedableRng;
let mut rng = IsaacRng::seed_from_u64(0); let mut rng = IsaacRng::seed_from_u64(0);
let a = rng.gen::<$t1>(); let a = rng.gen::<$t1>();
let b = rng.gen::<$t2>(); let b = rng.gen::<$t2>();
bh.iter(|| { bh.bench_function(stringify!($name), move |bh| bh.iter(|| {
a.$binop(&b) a.$binop(&b)
}) }));
} }
} }
); );
macro_rules! bench_binop_fn( macro_rules! bench_binop_fn(
($name: ident, $t1: ty, $t2: ty, $binop: path) => { ($name: ident, $t1: ty, $t2: ty, $binop: path) => {
#[bench] fn $name(bh: &mut criterion::Criterion) {
fn $name(bh: &mut Bencher) {
use rand::SeedableRng; use rand::SeedableRng;
let mut rng = IsaacRng::seed_from_u64(0); let mut rng = IsaacRng::seed_from_u64(0);
let a = rng.gen::<$t1>(); let a = rng.gen::<$t1>();
let b = rng.gen::<$t2>(); let b = rng.gen::<$t2>();
bh.iter(|| { bh.bench_function(stringify!($name), move |bh| bh.iter(|| {
$binop(&a, &b) $binop(&a, &b)
}) }));
} }
} }
); );
macro_rules! bench_unop_na( macro_rules! bench_unop_na(
($name: ident, $t: ty, $unop: ident) => { ($name: ident, $t: ty, $unop: ident) => {
#[bench] fn $name(bh: &mut criterion::Criterion) {
fn $name(bh: &mut Bencher) {
const LEN: usize = 1 << 13; const LEN: usize = 1 << 13;
use rand::SeedableRng; use rand::SeedableRng;
@ -60,21 +56,20 @@ macro_rules! bench_unop_na(
let elems: Vec<$t> = (0usize .. LEN).map(|_| rng.gen::<$t>()).collect(); let elems: Vec<$t> = (0usize .. LEN).map(|_| rng.gen::<$t>()).collect();
let mut i = 0; let mut i = 0;
bh.iter(|| { bh.bench_function(stringify!($name), move |bh| bh.iter(|| {
i = (i + 1) & (LEN - 1); i = (i + 1) & (LEN - 1);
unsafe { unsafe {
test::black_box(na::$unop(elems.get_unchecked(i))) test::black_box(na::$unop(elems.get_unchecked(i)))
} }
}) }));
} }
} }
); );
macro_rules! bench_unop( macro_rules! bench_unop(
($name: ident, $t: ty, $unop: ident) => { ($name: ident, $t: ty, $unop: ident) => {
#[bench] fn $name(bh: &mut criterion::Criterion) {
fn $name(bh: &mut Bencher) {
const LEN: usize = 1 << 13; const LEN: usize = 1 << 13;
use rand::SeedableRng; use rand::SeedableRng;
@ -83,21 +78,20 @@ macro_rules! bench_unop(
let mut elems: Vec<$t> = (0usize .. LEN).map(|_| rng.gen::<$t>()).collect(); let mut elems: Vec<$t> = (0usize .. LEN).map(|_| rng.gen::<$t>()).collect();
let mut i = 0; let mut i = 0;
bh.iter(|| { bh.bench_function(stringify!($name), move |bh| bh.iter(|| {
i = (i + 1) & (LEN - 1); i = (i + 1) & (LEN - 1);
unsafe { unsafe {
test::black_box(elems.get_unchecked_mut(i).$unop()) test::black_box(elems.get_unchecked_mut(i).$unop())
} }
}) }));
} }
} }
); );
macro_rules! bench_construction( macro_rules! bench_construction(
($name: ident, $constructor: path, $( $args: ident: $types: ty),*) => { ($name: ident, $constructor: path, $( $args: ident: $types: ty),*) => {
#[bench] fn $name(bh: &mut criterion::Criterion) {
fn $name(bh: &mut Bencher) {
const LEN: usize = 1 << 13; const LEN: usize = 1 << 13;
use rand::SeedableRng; use rand::SeedableRng;
@ -106,14 +100,14 @@ macro_rules! bench_construction(
$(let $args: Vec<$types> = (0usize .. LEN).map(|_| rng.gen::<$types>()).collect();)* $(let $args: Vec<$types> = (0usize .. LEN).map(|_| rng.gen::<$types>()).collect();)*
let mut i = 0; let mut i = 0;
bh.iter(|| { bh.bench_function(stringify!($name), move |bh| bh.iter(|| {
i = (i + 1) & (LEN - 1); i = (i + 1) & (LEN - 1);
unsafe { unsafe {
let res = $constructor($(*$args.get_unchecked(i),)*); let res = $constructor($(*$args.get_unchecked(i),)*);
test::black_box(res) test::black_box(res)
} }
}) }));
} }
} }
); );

View File

@ -196,3 +196,5 @@ fn mat100_from_fn(bench: &mut Bencher) {
fn mat500_from_fn(bench: &mut Bencher) { fn mat500_from_fn(bench: &mut Bencher) {
bench.iter(|| DMatrix::from_fn(500, 500, |a, b| a + b)) bench.iter(|| DMatrix::from_fn(500, 500, |a, b| a + b))
} }
criterion_group!(matrix, mat2_transpose);

View File

@ -1,2 +1,2 @@
mod matrix; pub mod matrix;
mod vector; pub mod vector;

View File

@ -1,7 +1,6 @@
use na::{DVector, Vector2, Vector3, Vector4, VectorN}; use na::{DVector, Vector2, Vector3, Vector4, VectorN};
use rand::{IsaacRng, Rng}; use rand::{IsaacRng, Rng};
use std::ops::{Add, Div, Mul, Sub}; use std::ops::{Add, Div, Mul, Sub};
use test::{self, Bencher};
use typenum::U10000; use typenum::U10000;
#[path = "../common/macros.rs"] #[path = "../common/macros.rs"]
@ -48,19 +47,17 @@ bench_unop!(vec4_normalize, Vector4<f32>, normalize);
bench_binop_ref!(vec10000_dot_f64, VectorN<f64, U10000>, VectorN<f64, U10000>, dot); bench_binop_ref!(vec10000_dot_f64, VectorN<f64, U10000>, VectorN<f64, U10000>, dot);
bench_binop_ref!(vec10000_dot_f32, VectorN<f32, U10000>, VectorN<f32, U10000>, dot); bench_binop_ref!(vec10000_dot_f32, VectorN<f32, U10000>, VectorN<f32, U10000>, dot);
#[bench] fn vec10000_axpy_f64(bh: &mut criterion::Criterion) {
fn vec10000_axpy_f64(bh: &mut Bencher) {
use rand::SeedableRng; use rand::SeedableRng;
let mut rng = IsaacRng::seed_from_u64(0); let mut rng = IsaacRng::seed_from_u64(0);
let mut a = DVector::new_random(10000); let mut a = DVector::new_random(10000);
let b = DVector::new_random(10000); let b = DVector::new_random(10000);
let n = rng.gen::<f64>(); let n = rng.gen::<f64>();
bh.iter(|| a.axpy(n, &b, 1.0)) bh.bench_function("", move |bh| bh.iter(|| a.axpy(n, &b, 1.0)));
} }
#[bench] fn vec10000_axpy_beta_f64(bh: &mut criterion::Criterion) {
fn vec10000_axpy_beta_f64(bh: &mut Bencher) {
use rand::SeedableRng; use rand::SeedableRng;
let mut rng = IsaacRng::seed_from_u64(0); let mut rng = IsaacRng::seed_from_u64(0);
let mut a = DVector::new_random(10000); let mut a = DVector::new_random(10000);
@ -68,27 +65,25 @@ fn vec10000_axpy_beta_f64(bh: &mut Bencher) {
let n = rng.gen::<f64>(); let n = rng.gen::<f64>();
let beta = rng.gen::<f64>(); let beta = rng.gen::<f64>();
bh.iter(|| a.axpy(n, &b, beta)) bh.bench_function("", move |bh| bh.iter(|| a.axpy(n, &b, beta)));
} }
#[bench] fn vec10000_axpy_f64_slice(bh: &mut criterion::Criterion) {
fn vec10000_axpy_f64_slice(bh: &mut Bencher) {
use rand::SeedableRng; use rand::SeedableRng;
let mut rng = IsaacRng::seed_from_u64(0); let mut rng = IsaacRng::seed_from_u64(0);
let mut a = DVector::new_random(10000); let mut a = DVector::new_random(10000);
let b = DVector::new_random(10000); let b = DVector::new_random(10000);
let n = rng.gen::<f64>(); let n = rng.gen::<f64>();
bh.iter(|| { bh.bench_function("", move |bh| bh.iter(|| {
let mut a = a.fixed_rows_mut::<U10000>(0); let mut a = a.fixed_rows_mut::<U10000>(0);
let b = b.fixed_rows::<U10000>(0); let b = b.fixed_rows::<U10000>(0);
a.axpy(n, &b, 1.0) a.axpy(n, &b, 1.0)
}) }));
} }
#[bench] fn vec10000_axpy_f64_static(bh: &mut criterion::Criterion) {
fn vec10000_axpy_f64_static(bh: &mut Bencher) {
use rand::SeedableRng; use rand::SeedableRng;
let mut rng = IsaacRng::seed_from_u64(0); let mut rng = IsaacRng::seed_from_u64(0);
let mut a = VectorN::<f64, U10000>::new_random(); let mut a = VectorN::<f64, U10000>::new_random();
@ -96,22 +91,20 @@ fn vec10000_axpy_f64_static(bh: &mut Bencher) {
let n = rng.gen::<f64>(); let n = rng.gen::<f64>();
// NOTE: for some reasons, it is much faster if the arument are boxed (Box::new(VectorN...)). // NOTE: for some reasons, it is much faster if the arument are boxed (Box::new(VectorN...)).
bh.iter(|| a.axpy(n, &b, 1.0)) bh.bench_function("", move |bh| bh.iter(|| a.axpy(n, &b, 1.0)));
} }
#[bench] fn vec10000_axpy_f32(bh: &mut criterion::Criterion) {
fn vec10000_axpy_f32(bh: &mut Bencher) {
use rand::SeedableRng; use rand::SeedableRng;
let mut rng = IsaacRng::seed_from_u64(0); let mut rng = IsaacRng::seed_from_u64(0);
let mut a = DVector::new_random(10000); let mut a = DVector::new_random(10000);
let b = DVector::new_random(10000); let b = DVector::new_random(10000);
let n = rng.gen::<f32>(); let n = rng.gen::<f32>();
bh.iter(|| a.axpy(n, &b, 1.0)) bh.bench_function("", move |bh| bh.iter(|| a.axpy(n, &b, 1.0)));
} }
#[bench] fn vec10000_axpy_beta_f32(bh: &mut criterion::Criterion) {
fn vec10000_axpy_beta_f32(bh: &mut Bencher) {
use rand::SeedableRng; use rand::SeedableRng;
let mut rng = IsaacRng::seed_from_u64(0); let mut rng = IsaacRng::seed_from_u64(0);
let mut a = DVector::new_random(10000); let mut a = DVector::new_random(10000);
@ -119,5 +112,7 @@ fn vec10000_axpy_beta_f32(bh: &mut Bencher) {
let n = rng.gen::<f32>(); let n = rng.gen::<f32>();
let beta = rng.gen::<f32>(); let beta = rng.gen::<f32>();
bh.iter(|| a.axpy(n, &b, beta)) bh.bench_function("", move |bh| bh.iter(|| a.axpy(n, &b, beta)));
} }
criterion_group!(vector, vec10000_axpy_f64_static);

View File

@ -6,15 +6,20 @@ extern crate rand;
extern crate test; extern crate test;
extern crate typenum; extern crate typenum;
#[macro_use]
extern crate criterion;
use na::DMatrix; use na::DMatrix;
use rand::{IsaacRng, Rng}; use rand::{IsaacRng, Rng};
mod core; pub mod core;
mod geometry; pub mod geometry;
mod linalg; pub mod linalg;
fn reproductible_dmatrix(nrows: usize, ncols: usize) -> DMatrix<f64> { fn reproductible_dmatrix(nrows: usize, ncols: usize) -> DMatrix<f64> {
use rand::SeedableRng; use rand::SeedableRng;
let mut rng = IsaacRng::seed_from_u64(0); let mut rng = IsaacRng::seed_from_u64(0);
DMatrix::<f64>::from_fn(nrows, ncols, |_, _| rng.gen()) DMatrix::<f64>::from_fn(nrows, ncols, |_, _| rng.gen())
} }
criterion_main!(core::matrix::matrix, core::vector::vector);