-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #119430 - NCGThompson:int-pow-bench, r=cuviper
Add Benchmarks for int_pow Methods. There is quite a bit of room for improvement in performance of the `int_pow` family of methods. I added benchmarks for those functions. In particular, there are benchmarks for small compile-time bases to measure the effect of #114390. ~~I added a lot (245), but all but 22 of them are marked with `#[ignore]`. There are a lot of macros, and I would appreciate feedback on how to simplify them.~~ ~~To run benches relevant to #114390, use `./x bench core --stage 1 -- pow_base_const --include-ignored`.~~
- Loading branch information
Showing
4 changed files
with
100 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
use rand::Rng; | ||
use test::{black_box, Bencher}; | ||
|
||
const ITERATIONS: usize = 128; // Uses an ITERATIONS * 20 Byte stack allocation | ||
type IntType = i128; // Hardest native type to multiply | ||
const EXPONENT_MAX: u32 = 31; | ||
const MAX_BASE: IntType = 17; // +-17 ** 31 <= IntType::MAX | ||
|
||
macro_rules! pow_bench_template { | ||
($name:ident, $inner_macro:ident, $base_macro:ident) => { | ||
#[bench] | ||
fn $name(bench: &mut Bencher) { | ||
// Frequent black_box calls can add latency and prevent optimizations, so for | ||
// variable parameters we premake an array and pass the | ||
// reference through black_box outside of the loop. | ||
let mut rng = crate::bench_rng(); | ||
let base_array: [IntType; ITERATIONS] = | ||
core::array::from_fn(|_| rng.gen_range((-MAX_BASE..=MAX_BASE))); | ||
let exp_array: [u32; ITERATIONS] = | ||
core::array::from_fn(|_| rng.gen_range((0..=EXPONENT_MAX))); | ||
|
||
bench.iter(|| { | ||
#[allow(unused, unused_mut)] | ||
let mut base_iter = black_box(&base_array).into_iter(); | ||
let mut exp_iter = black_box(&exp_array).into_iter(); | ||
|
||
(0..ITERATIONS).fold((0 as IntType, false), |acc, _| { | ||
// Sometimes constants don't propogate all the way to the | ||
// inside of the loop, so we call a custom expression every cycle | ||
// rather than iter::repeat(CONST) | ||
let base: IntType = $base_macro!(base_iter); | ||
let exp: u32 = *exp_iter.next().unwrap(); | ||
|
||
let r: (IntType, bool) = $inner_macro!(base, exp); | ||
(acc.0 ^ r.0, acc.1 ^ r.1) | ||
}) | ||
}); | ||
} | ||
}; | ||
} | ||
|
||
// This may panic if it overflows. | ||
macro_rules! inner_pow { | ||
($base:ident, $exp:ident) => { | ||
($base.pow($exp), false) | ||
}; | ||
} | ||
|
||
macro_rules! inner_wrapping { | ||
($base:ident, $exp:ident) => { | ||
($base.wrapping_pow($exp), false) | ||
}; | ||
} | ||
|
||
macro_rules! inner_overflowing { | ||
($base:ident, $exp:ident) => { | ||
$base.overflowing_pow($exp) | ||
}; | ||
} | ||
|
||
// This will panic if it overflows. | ||
macro_rules! inner_checked_unwrapped { | ||
($base:ident, $exp:ident) => { | ||
($base.checked_pow($exp).unwrap(), false) | ||
}; | ||
} | ||
|
||
macro_rules! inner_saturating { | ||
($base:ident, $exp:ident) => { | ||
($base.saturating_pow($exp), false) | ||
}; | ||
} | ||
|
||
macro_rules! make_const_base { | ||
($name:ident, $x:literal) => { | ||
macro_rules! $name { | ||
($iter:ident) => { | ||
$x | ||
}; | ||
} | ||
}; | ||
} | ||
|
||
make_const_base!(const_base_m7, -7); | ||
make_const_base!(const_base_m8, -8); | ||
|
||
macro_rules! variable_base { | ||
($iter:ident) => { | ||
*$iter.next().unwrap() | ||
}; | ||
} | ||
|
||
pow_bench_template!(pow_variable, inner_pow, variable_base); | ||
pow_bench_template!(wrapping_pow_variable, inner_wrapping, variable_base); | ||
pow_bench_template!(overflowing_pow_variable, inner_overflowing, variable_base); | ||
pow_bench_template!(checked_pow_variable, inner_checked_unwrapped, variable_base); | ||
pow_bench_template!(saturating_pow_variable, inner_saturating, variable_base); | ||
pow_bench_template!(pow_m7, inner_pow, const_base_m7); | ||
pow_bench_template!(pow_m8, inner_pow, const_base_m8); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
mod dec2flt; | ||
mod flt2dec; | ||
mod int_log; | ||
mod int_pow; | ||
|
||
use std::str::FromStr; | ||
use test::{black_box, Bencher}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.