Skip to content

Commit

Permalink
Add simple icount benchmarks for u256 operations
Browse files Browse the repository at this point in the history
  • Loading branch information
tgross35 committed Feb 8, 2025
1 parent 670f8a8 commit 555a29c
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 1 deletion.
101 changes: 101 additions & 0 deletions crates/libm-test/benches/icount.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
//! Benchmarks that use `iai-cachegrind` to be reasonably CI-stable.
use std::hint::black_box;
use std::ops::Shr;

use iai_callgrind::{library_benchmark, library_benchmark_group, main};
use libm::support::{HInt, u256};
use libm_test::gen::spaced;
use libm_test::{CheckBasis, CheckCtx, GeneratorKind, MathOp, OpRustArgs, TupleCall, op};

Expand Down Expand Up @@ -51,8 +53,107 @@ libm_macros::for_each_function! {
callback: icount_benches,
}

fn setup_u128_mul() -> Vec<(u128, u128)> {
let step = u128::MAX / 300;
let mut x = 0u128;
let mut y = 0u128;
let mut v = Vec::new();

loop {
'inner: loop {
match y.checked_add(step) {
Some(new) => y = new,
None => break 'inner,
}

v.push((x, y))
}

match x.checked_add(step) {
Some(new) => x = new,
None => break,
}
}

v
}

/*
fn setup_u256_add() -> Vec<(u256, u256)> {
let mut v = Vec::new();
for (x, y) in setup_u128_mul() {
// square the u128 inputs to cover most of the u256 range
v.push((x.widen_mul(x), y.widen_mul(y)));
}
// Doesn't get covered by `u128:MAX^2`
v.push((u256::MAX, u256::MAX));
v
}
*/

fn setup_u256_shift() -> Vec<(u256, u32)> {
let mut v = Vec::new();

for (x, _) in setup_u128_mul() {
let x2 = x.widen_mul(x);
for y in 0u32..256 {
v.push((x2, y));
}
}

v
}

#[library_benchmark]
#[bench::linspace(setup_u128_mul())]
fn icount_bench_u128_widen_mul(cases: Vec<(u128, u128)>) {
let f = black_box(u128::zero_widen_mul);
for (x, y) in cases.iter().copied() {
f(x, y);
}
}

library_benchmark_group!(
name = icount_bench_u128_widen_mul_group;
benchmarks = icount_bench_u128_widen_mul
);

/* Not yet implemented
#[library_benchmark]
#[bench::linspace(setup_u256_add())]
fn icount_bench_u256_add(cases: Vec<(u256, u256)>) {
let f = black_box(u256::add);
for (x, y) in cases.iter().copied() {
f(x, y);
}
}
library_benchmark_group!(
name = icount_bench_u256_add_group;
benchmarks = icount_bench_u256_add
);
*/

#[library_benchmark]
#[bench::linspace(setup_u256_shift())]
fn icount_bench_u256_shr(cases: Vec<(u256, u32)>) {
let f = black_box(u256::shr);
for (x, y) in cases.iter().copied() {
f(x, y);
}
}

library_benchmark_group!(
name = icount_bench_u256_shr_group;
benchmarks = icount_bench_u256_shr
);

main!(
library_benchmark_groups =
// u256-related benchmarks
icount_bench_u128_widen_mul_group,
// icount_bench_u256_add_group,
icount_bench_u256_shr_group,
// verify-apilist-start
// verify-sorted-start
icount_bench_acos_group,
Expand Down
2 changes: 1 addition & 1 deletion src/math/support/big.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const U128_LO_MASK: u128 = u64::MAX as u128;
pub struct u256(pub [u64; 4]);

impl u256 {
#[cfg(test)]
#[allow(unused)]
pub const MAX: Self = Self([u64::MAX, u64::MAX, u64::MAX, u64::MAX]);

/// Reinterpret as a signed integer
Expand Down
2 changes: 2 additions & 0 deletions src/math/support/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ mod float_traits;
pub mod hex_float;
mod int_traits;

#[allow(unused_imports)]
pub use big::{i256, u256};
#[allow(unused_imports)]
pub use float_traits::{DFloat, Float, HFloat, IntTy};
pub(crate) use float_traits::{f32_from_bits, f64_from_bits};
Expand Down

0 comments on commit 555a29c

Please sign in to comment.