Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Commit 6b2a1f3

Browse files
authored
Merge pull request #314 from tgross35/musl-benchmarks
Add benchmarks against musl libm
2 parents f4c65b5 + f951c18 commit 6b2a1f3

File tree

7 files changed

+137
-134
lines changed

7 files changed

+137
-134
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ jobs:
125125
- uses: Swatinem/rust-cache@v2
126126
- name: Download musl source
127127
run: ./ci/download-musl.sh
128-
- run: cargo bench --all
128+
- run: cargo bench --all --features libm-test/short-benchmarks,libm-test/build-musl
129129

130130
msrv:
131131
name: Check MSRV

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ force-soft-floats = []
3838
resolver = "2"
3939
members = [
4040
"crates/compiler-builtins-smoke-test",
41-
"crates/libm-bench",
4241
"crates/libm-macros",
4342
"crates/libm-test",
4443
"crates/musl-math-sys",

ci/run.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,8 @@ else
8383
# unstable with a feature
8484
$cmd --features "unstable-intrinsics"
8585
$cmd --release --features "unstable-intrinsics"
86+
87+
# Make sure benchmarks have correct results
88+
$cmd --benches
89+
$cmd --benches --release
8690
fi

crates/libm-bench/Cargo.toml

Lines changed: 0 additions & 16 deletions
This file was deleted.

crates/libm-bench/benches/bench.rs

Lines changed: 0 additions & 116 deletions
This file was deleted.

crates/libm-test/Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ test-multiprecision = ["dep:az", "dep:rug"]
1515
# Build our own musl for testing and benchmarks
1616
build-musl = ["dep:musl-math-sys"]
1717

18+
# Enable report generation without bringing in more dependencies by default
19+
benchmarking-reports = ["criterion/plotters", "criterion/html_reports"]
20+
21+
# Run with a reduced set of benchmarks, such as for CI
22+
short-benchmarks = []
23+
1824
[dependencies]
1925
anyhow = "1.0.90"
2026
az = { version = "1.2.1", optional = true }
@@ -32,3 +38,10 @@ getrandom = { version = "0.2", features = ["js"] }
3238

3339
[build-dependencies]
3440
rand = { version = "0.8.5", optional = true }
41+
42+
[dev-dependencies]
43+
criterion = { version = "0.5.1", default-features = false, features = ["cargo_bench_support"] }
44+
45+
[[bench]]
46+
name = "random"
47+
harness = false

crates/libm-test/benches/random.rs

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
use std::hint::black_box;
2+
use std::time::Duration;
3+
4+
use criterion::{Criterion, criterion_main};
5+
use libm_test::gen::random;
6+
use libm_test::{CheckBasis, CheckCtx, TupleCall};
7+
8+
/// Benchmark with this many items to get a variety
9+
const BENCH_ITER_ITEMS: usize = if cfg!(feature = "short-benchmarks") { 50 } else { 500 };
10+
11+
macro_rules! musl_rand_benches {
12+
(
13+
fn_name: $fn_name:ident,
14+
CFn: $CFn:ty,
15+
CArgs: $CArgs:ty,
16+
CRet: $CRet:ty,
17+
RustFn: $RustFn:ty,
18+
RustArgs: $RustArgs:ty,
19+
RustRet: $RustRet:ty,
20+
fn_extra: $skip_on_i586:expr,
21+
) => {
22+
paste::paste! {
23+
fn [< musl_bench_ $fn_name >](c: &mut Criterion) {
24+
let fn_name = stringify!($fn_name);
25+
26+
let ulp = libm_test::musl_allowed_ulp(fn_name);
27+
let ctx = CheckCtx::new(ulp, fn_name, CheckBasis::Musl);
28+
let benchvec: Vec<_> = random::get_test_cases::<$RustArgs>(&ctx)
29+
.take(BENCH_ITER_ITEMS)
30+
.collect();
31+
32+
// Perform a sanity check that we are benchmarking the same thing
33+
// Don't test against musl if it is not available
34+
#[cfg(feature = "build-musl")]
35+
for input in benchvec.iter().copied() {
36+
use anyhow::Context;
37+
use libm_test::{CheckBasis, CheckCtx, CheckOutput};
38+
39+
if cfg!(x86_no_sse) && $skip_on_i586 {
40+
break;
41+
}
42+
43+
let musl_res = input.call(musl_math_sys::$fn_name as $CFn);
44+
let crate_res = input.call(libm::$fn_name as $RustFn);
45+
46+
let ctx = CheckCtx::new(ulp, fn_name, CheckBasis::Musl);
47+
crate_res.validate(musl_res, input, &ctx).context(fn_name).unwrap();
48+
}
49+
50+
/* Function pointers are black boxed to avoid inlining in the benchmark loop */
51+
52+
let mut group = c.benchmark_group(fn_name);
53+
group.bench_function("crate", |b| b.iter(|| {
54+
let f = black_box(libm::$fn_name as $RustFn);
55+
for input in benchvec.iter().copied() {
56+
input.call(f);
57+
}
58+
}));
59+
60+
// Don't test against musl if it is not available
61+
#[cfg(feature = "build-musl")]
62+
group.bench_function("musl", |b| b.iter(|| {
63+
let f = black_box(musl_math_sys::$fn_name as $CFn);
64+
for input in benchvec.iter().copied() {
65+
input.call(f);
66+
}
67+
}));
68+
}
69+
}
70+
};
71+
}
72+
73+
libm_macros::for_each_function! {
74+
callback: musl_rand_benches,
75+
skip: [],
76+
fn_extra: match MACRO_FN_NAME {
77+
// FIXME(correctness): wrong result on i586
78+
exp10 | exp10f | exp2 | exp2f => true,
79+
_ => false
80+
}
81+
}
82+
83+
macro_rules! run_callback {
84+
(
85+
fn_name: $fn_name:ident,
86+
CFn: $_CFn:ty,
87+
CArgs: $_CArgs:ty,
88+
CRet: $_CRet:ty,
89+
RustFn: $_RustFn:ty,
90+
RustArgs: $_RustArgs:ty,
91+
RustRet: $_RustRet:ty,
92+
extra: [$criterion:ident],
93+
) => {
94+
paste::paste! {
95+
[< musl_bench_ $fn_name >](&mut $criterion)
96+
}
97+
};
98+
}
99+
100+
pub fn musl_random() {
101+
let mut criterion = Criterion::default();
102+
103+
// For CI, run a short 0.5s warmup and 1.0s tests. This makes benchmarks complete in
104+
// about the same time as other tests.
105+
if cfg!(feature = "short-benchmarks") {
106+
criterion = criterion
107+
.warm_up_time(Duration::from_millis(500))
108+
.measurement_time(Duration::from_millis(1000));
109+
}
110+
111+
criterion = criterion.configure_from_args();
112+
113+
libm_macros::for_each_function! {
114+
callback: run_callback,
115+
extra: [criterion],
116+
};
117+
}
118+
119+
criterion_main!(musl_random);

0 commit comments

Comments
 (0)