Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restructure criterion benchmarks into groups #8

Merged
merged 12 commits into from
Jul 21, 2024
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

81 changes: 40 additions & 41 deletions benches/all_equal.rs
Original file line number Diff line number Diff line change
@@ -1,54 +1,53 @@
#![feature(portable_simd)]
#![feature(is_sorted)]

use criterion::{black_box, criterion_group, criterion_main, Criterion};
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use itertools::Itertools;
use simd_itertools::AllEqualSimd;
use simd_itertools::SIMD_LEN;
use std::fmt::Debug;
use std::simd::prelude::SimdPartialEq;
use std::simd::Mask;
use std::simd::Simd;
use std::simd::SimdElement;
use std::time::Duration;

fn benchmark_all_equal<'a, T: 'static + Copy + PartialEq + Default + Debug>(
_c: &mut Criterion,
name: &str,
len: usize,
) where
use simd_itertools::{AllEqualSimd, SIMD_LEN};
use std::{
fmt::Debug,
simd::{prelude::SimdPartialEq, Mask, Simd, SimdElement},
};

fn benchmark_all_equal<'a, T: 'static + Copy + PartialEq + Default + Debug>(c: &mut Criterion)
where
T: SimdElement + std::cmp::PartialEq,
Simd<T, SIMD_LEN>: SimdPartialEq<Mask = Mask<T::Mask, SIMD_LEN>>,
{
let v1 = vec![T::default(); len];

let mut group = Criterion::default()
.warm_up_time(Duration::from_secs(1))
.measurement_time(Duration::from_secs(1));

group.bench_function(&format!("SIMD all_equal {} {}", name, len), |b| {
b.iter(|| black_box(v1.iter().all_equal_simd()))
});
group.bench_function(&format!("Scalar all_equal {} {}", name, len), |b| {
b.iter(|| black_box(v1.iter().all_equal()))
});
let mut group = c.benchmark_group(format!("all-equal-{}", std::any::type_name::<T>()));
let mut len = 1;

while len < (1 << 11) {
let v1 = vec![T::default(); len];

group.throughput(Throughput::Elements(len as u64));

group.bench_function(BenchmarkId::new("SIMD", len), |b| {
b.iter(|| black_box(v1.iter().all_equal_simd()))
});
group.bench_function(BenchmarkId::new("Scalar", len), |b| {
b.iter(|| black_box(v1.iter().all_equal()))
});

len *= 10;
}

group.finish();
}

fn criterion_benchmark(c: &mut Criterion) {
for n in (0..200).map(|x| x * 10) {
benchmark_all_equal::<u8>(c, "u8", n);
benchmark_all_equal::<i8>(c, "i8", n);
benchmark_all_equal::<u16>(c, "u16", n);
benchmark_all_equal::<i16>(c, "i16", n);
benchmark_all_equal::<u32>(c, "u32", n);
benchmark_all_equal::<i32>(c, "i32", n);
benchmark_all_equal::<u64>(c, "u64", n);
benchmark_all_equal::<i64>(c, "i64", n);
benchmark_all_equal::<f32>(c, "f32", n);
benchmark_all_equal::<f64>(c, "f64", n);
benchmark_all_equal::<isize>(c, "isize", n);
benchmark_all_equal::<usize>(c, "usize", n);
}
benchmark_all_equal::<u8>(c);
benchmark_all_equal::<i8>(c);
benchmark_all_equal::<u16>(c);
benchmark_all_equal::<i16>(c);
benchmark_all_equal::<u32>(c);
benchmark_all_equal::<i32>(c);
benchmark_all_equal::<u64>(c);
benchmark_all_equal::<i64>(c);
benchmark_all_equal::<f32>(c);
benchmark_all_equal::<f64>(c);
benchmark_all_equal::<isize>(c);
benchmark_all_equal::<usize>(c);
}

criterion_group!(benches, criterion_benchmark);
Expand Down
113 changes: 60 additions & 53 deletions benches/contains.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,84 @@
#![feature(is_sorted)]
#![feature(sort_floats)]

use criterion::{black_box, criterion_group, criterion_main, Criterion};
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use itertools::Itertools;
use simd_itertools::ContainsSimd;
use simd_itertools::SIMD_LEN;
use std::fmt::Debug;
use std::simd::prelude::SimdPartialEq;
use std::simd::Mask;
use std::simd::{Simd, SimdElement};
use std::time::Duration;
use simd_itertools::{ContainsSimd, SIMD_LEN};
use std::{
fmt::Debug,
simd::{prelude::SimdPartialEq, Mask, Simd, SimdElement},
};

fn benchmark_contains<'a, T: 'static + Copy + PartialEq + Default + Debug>(
_c: &mut Criterion,
name: &str,
len: usize,
) where
fn benchmark_contains<'a, T: 'static + Copy + PartialEq + Default + Debug>(c: &mut Criterion)
where
T: SimdElement + std::cmp::PartialEq + TryFrom<i32> + Debug,
Simd<T, SIMD_LEN>: SimdPartialEq<Mask = Mask<T::Mask, SIMD_LEN>>,
<T as TryFrom<i32>>::Error: Debug,
{
let v1 = vec![T::default(); len];
let needle: T = 55.try_into().unwrap();
let mut group = c.benchmark_group(format!("contains-{}", std::any::type_name::<T>()));
let mut len = 1;

let mut group = Criterion::default()
.warm_up_time(Duration::from_secs(1))
.measurement_time(Duration::from_secs(1));
while len < (1 << 11) {
let v1 = vec![T::default(); len];
let needle: T = 55.try_into().unwrap();

group.bench_function(&format!("SIMD contains {} {}", name, len), |b| {
b.iter(|| black_box(v1.iter().contains_simd(&needle)))
});
group.bench_function(&format!("Scalar contains {} {}", name, len), |b| {
b.iter(|| black_box(v1.iter().contains(&needle)))
});
group.throughput(Throughput::Elements(len as u64));

group.bench_function(BenchmarkId::new("SIMD", len), |b| {
b.iter(|| black_box(v1.iter().contains_simd(&needle)))
});
group.bench_function(BenchmarkId::new("Scalar", len), |b| {
b.iter(|| black_box(v1.iter().contains(&needle)))
});

len *= 10;
}

group.finish();
}

fn benchmark_contains_floats<'a, T: 'static + Copy + PartialEq + Default + Debug>(
c: &mut Criterion,
name: &str,
len: usize,
) where
fn benchmark_contains_floats<'a, T: 'static + Copy + PartialEq + Default + Debug>(c: &mut Criterion)
where
T: SimdElement + std::cmp::PartialEq + TryFrom<f32> + Debug + std::convert::From<f32>,
Simd<T, SIMD_LEN>: SimdPartialEq<Mask = Mask<T::Mask, SIMD_LEN>>,
<T as TryFrom<f32>>::Error: Debug,
{
let v1 = vec![T::default(); len];
let v2 = vec![T::default(); len];
let needle: T = 55.0.try_into().unwrap();
assert_eq!(v1, v2);
let mut group = c.benchmark_group(format!("contains-float-{}", std::any::type_name::<T>()));
let mut len = 1;

while len < (1 << 11) {
let v1 = vec![T::default(); len];
let v2 = vec![T::default(); len];
let needle: T = 55.0.try_into().unwrap();
assert_eq!(v1, v2);

c.bench_function(&format!("SIMD contains {}", name), |b| {
b.iter(|| black_box(v1.iter().contains_simd(&needle)))
});
c.bench_function(&format!("trivial contains {}", name), |b| {
b.iter(|| black_box(v1.iter().contains(&needle)))
});
group.throughput(Throughput::Elements(len as u64));

group.bench_function(BenchmarkId::new("SIMD", len), |b| {
b.iter(|| black_box(v1.iter().contains_simd(&needle)))
});
group.bench_function(BenchmarkId::new("Scalar", len), |b| {
b.iter(|| black_box(v1.iter().contains(&needle)))
});

len *= 10;
}
group.finish();
}

fn criterion_benchmark(c: &mut Criterion) {
for n in (0..200).map(|x| x * 10) {
benchmark_contains::<u8>(c, "u8", n);
benchmark_contains::<i8>(c, "i8", n);
benchmark_contains::<u16>(c, "u16", n);
benchmark_contains::<i16>(c, "i16", n);
benchmark_contains::<u32>(c, "u32", n);
benchmark_contains::<i32>(c, "i32", n);
benchmark_contains::<u64>(c, "u64", n);
benchmark_contains::<i64>(c, "i64", n);
benchmark_contains::<isize>(c, "isize", n);
benchmark_contains::<usize>(c, "usize", n);
benchmark_contains_floats::<f32>(c, "f32", n);
benchmark_contains_floats::<f64>(c, "f64", n);
}
benchmark_contains::<u8>(c);
benchmark_contains::<i8>(c);
benchmark_contains::<u16>(c);
benchmark_contains::<i16>(c);
benchmark_contains::<u32>(c);
benchmark_contains::<i32>(c);
benchmark_contains::<u64>(c);
benchmark_contains::<i64>(c);
benchmark_contains::<isize>(c);
benchmark_contains::<usize>(c);
benchmark_contains_floats::<f32>(c);
benchmark_contains_floats::<f64>(c);
}

criterion_group!(benches, criterion_benchmark);
Expand Down
83 changes: 42 additions & 41 deletions benches/eq.rs
Original file line number Diff line number Diff line change
@@ -1,52 +1,53 @@
#![feature(portable_simd)]

use criterion::{black_box, criterion_group, criterion_main, Criterion};
use simd_itertools::EqSimd;
use simd_itertools::SIMD_LEN;
use std::fmt::Debug;
use std::simd::prelude::SimdPartialEq;
use std::simd::Mask;
use std::simd::{Simd, SimdElement};
use std::time::Duration;

fn benchmark_contains<'a, T: 'static + Copy + PartialEq + Default + Debug>(
_c: &mut Criterion,
name: &str,
len: usize,
) where
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use simd_itertools::{EqSimd, SIMD_LEN};
use std::{
fmt::Debug,
simd::{prelude::SimdPartialEq, Mask, Simd, SimdElement},
};

fn benchmark_eq<'a, T: 'static + Copy + PartialEq + Default + Debug>(c: &mut Criterion)
where
T: SimdElement + std::cmp::PartialEq,
Simd<T, SIMD_LEN>: SimdPartialEq<Mask = Mask<T::Mask, SIMD_LEN>>,
{
let v1 = black_box(vec![T::default(); len]);
let v2 = black_box(vec![T::default(); len]);

let mut group = Criterion::default()
.warm_up_time(Duration::from_secs(1))
.measurement_time(Duration::from_secs(1));

group.bench_function(&format!("SIMD eq {} {}", name, len), |b| {
b.iter(|| black_box(v1.iter().eq_simd(&v2.iter())))
});
group.bench_function(&format!("Scalar eq {} {}", name, len), |b| {
b.iter(|| black_box(v1.iter().eq(&v2)))
});
let mut group = c.benchmark_group(format!("eq-{}", std::any::type_name::<T>()));
let mut len = 1;

while len < (1 << 11) {
let v1 = black_box(vec![T::default(); len]);
let v2 = black_box(vec![T::default(); len]);

group.throughput(Throughput::Elements(len as u64));

group.bench_function(BenchmarkId::new("SIMD", len), |b| {
b.iter(|| black_box(v1.iter().eq_simd(&v2.iter())))
});
group.bench_function(BenchmarkId::new("Scalar", len), |b| {
b.iter(|| black_box(v1.iter().eq(&v2)))
});

len *= 10;
}

group.finish();
}

fn criterion_benchmark(c: &mut Criterion) {
for n in (0..200).map(|x| x * 10) {
benchmark_contains::<u8>(c, "u8", n);
benchmark_contains::<i8>(c, "i8", n);
benchmark_contains::<u16>(c, "u16", n);
benchmark_contains::<i16>(c, "i16", n);
benchmark_contains::<u32>(c, "u32", n);
benchmark_contains::<i32>(c, "i32", n);
benchmark_contains::<u64>(c, "u64", n);
benchmark_contains::<i64>(c, "i64", n);
benchmark_contains::<isize>(c, "isize", n);
benchmark_contains::<usize>(c, "usize", n);
benchmark_contains::<f32>(c, "f32", n);
benchmark_contains::<f64>(c, "f64", n);
}
benchmark_eq::<u8>(c);
benchmark_eq::<i8>(c);
benchmark_eq::<u16>(c);
benchmark_eq::<i16>(c);
benchmark_eq::<u32>(c);
benchmark_eq::<i32>(c);
benchmark_eq::<u64>(c);
benchmark_eq::<i64>(c);
benchmark_eq::<isize>(c);
benchmark_eq::<usize>(c);
benchmark_eq::<f32>(c);
benchmark_eq::<f64>(c);
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
Loading