Skip to content

Commit

Permalink
Migrate to core::hint::black_box() (#16980)
Browse files Browse the repository at this point in the history
# Objective

Many of our benchmarks use
[`criterion::black_box()`](https://docs.rs/criterion/latest/criterion/fn.black_box.html),
which is used to prevent the compiler from optimizing away computation
that we're trying to time. This can be slow, though, because
`criterion::black_box()` forces a point read each time it is called
through
[`ptr::road_volatile()`](https://doc.rust-lang.org/stable/std/ptr/fn.read_volatile.html).

In Rust 1.66, the standard library introduced
[`core::hint::black_box()`](https://doc.rust-lang.org/nightly/std/hint/fn.black_box.html)
(and `std::hint::black_box()`). This is an intended replacement for
`criterion`'s version that uses compiler intrinsics instead of volatile
pointer reads, and thus has no runtime overhead. This increases
benchmark accuracy, which is always nice 👍

Note that benchmarks may _appear_ to improve in performance after this
change, but that's just because we are eliminating the pointer read
overhead.

## Solution

- Deny `criterion::black_box` in `clippy.toml`.
- Fix all imports.

## Testing

- `cargo clippy -p benches --benches`
  • Loading branch information
BD103 authored Dec 29, 2024
1 parent f391522 commit 17ad855
Show file tree
Hide file tree
Showing 17 changed files with 48 additions and 23 deletions.
4 changes: 3 additions & 1 deletion benches/benches/bevy_ecs/change_detection.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use core::hint::black_box;

use bevy_ecs::{
component::{Component, Mutable},
entity::Entity,
prelude::{Added, Changed, EntityWorldMut, QueryState},
query::QueryFilter,
world::World,
};
use criterion::{black_box, criterion_group, Criterion};
use criterion::{criterion_group, Criterion};
use rand::{prelude::SliceRandom, SeedableRng};
use rand_chacha::ChaCha8Rng;

Expand Down
4 changes: 3 additions & 1 deletion benches/benches/bevy_ecs/empty_archetypes.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use core::hint::black_box;

use bevy_ecs::{component::Component, prelude::*, schedule::ExecutorKind, world::World};
use criterion::{black_box, criterion_group, BenchmarkId, Criterion};
use criterion::{criterion_group, BenchmarkId, Criterion};

criterion_group!(benches, empty_archetypes);

Expand Down
4 changes: 3 additions & 1 deletion benches/benches/bevy_ecs/entity_cloning.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use core::hint::black_box;

use bevy_ecs::bundle::Bundle;
use bevy_ecs::reflect::AppTypeRegistry;
use bevy_ecs::{component::Component, reflect::ReflectComponent, world::World};
use bevy_hierarchy::{BuildChildren, CloneEntityHierarchyExt};
use bevy_math::Mat4;
use bevy_reflect::{GetTypeRegistration, Reflect};
use criterion::{black_box, criterion_group, criterion_main, Bencher, Criterion};
use criterion::{criterion_group, criterion_main, Bencher, Criterion};

criterion_group!(benches, reflect_benches, clone_benches);
criterion_main!(benches);
Expand Down
4 changes: 3 additions & 1 deletion benches/benches/bevy_ecs/observers/propagation.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use core::hint::black_box;

use bevy_ecs::{
component::Component, entity::Entity, event::Event, observer::Trigger, world::World,
};
use bevy_hierarchy::{BuildChildren, Parent};

use criterion::{black_box, Criterion};
use criterion::Criterion;
use rand::SeedableRng;
use rand::{seq::IteratorRandom, Rng};
use rand_chacha::ChaCha8Rng;
Expand Down
4 changes: 3 additions & 1 deletion benches/benches/bevy_ecs/observers/simple.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use core::hint::black_box;

use bevy_ecs::{entity::Entity, event::Event, observer::Trigger, world::World};

use criterion::{black_box, Criterion};
use criterion::Criterion;
use rand::{prelude::SliceRandom, SeedableRng};
use rand_chacha::ChaCha8Rng;
fn deterministic_rand() -> ChaCha8Rng {
Expand Down
4 changes: 3 additions & 1 deletion benches/benches/bevy_ecs/world/commands.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use core::hint::black_box;

use bevy_ecs::{
component::Component,
system::Commands,
world::{Command, CommandQueue, World},
};
use criterion::{black_box, Criterion};
use criterion::Criterion;

#[derive(Component)]
struct A;
Expand Down
4 changes: 3 additions & 1 deletion benches/benches/bevy_ecs/world/world_get.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use core::hint::black_box;

use bevy_ecs::{
bundle::Bundle,
component::Component,
entity::Entity,
system::{Query, SystemState},
world::World,
};
use criterion::{black_box, Criterion};
use criterion::Criterion;
use rand::{prelude::SliceRandom, SeedableRng};
use rand_chacha::ChaCha8Rng;

Expand Down
4 changes: 3 additions & 1 deletion benches/benches/bevy_math/bezier.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use criterion::{black_box, criterion_group, Criterion};
use core::hint::black_box;

use criterion::{criterion_group, Criterion};

use bevy_math::prelude::*;

Expand Down
4 changes: 3 additions & 1 deletion benches/benches/bevy_picking/ray_mesh_intersection.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use core::hint::black_box;

use bevy_math::{Dir3, Mat4, Ray3d, Vec3};
use bevy_picking::mesh_picking::ray_cast;
use criterion::{black_box, criterion_group, Criterion};
use criterion::{criterion_group, Criterion};

fn ptoxznorm(p: u32, size: u32) -> (f32, f32) {
let ij = (p / (size), p % (size));
Expand Down
6 changes: 3 additions & 3 deletions benches/benches/bevy_reflect/list.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use core::{iter, time::Duration};
use core::{hint::black_box, iter, time::Duration};

use benches::bench;
use bevy_reflect::{DynamicList, List};
use criterion::{
black_box, criterion_group, measurement::Measurement, AxisScale, BatchSize, BenchmarkGroup,
BenchmarkId, Criterion, PlotConfiguration, Throughput,
criterion_group, measurement::Measurement, AxisScale, BatchSize, BenchmarkGroup, BenchmarkId,
Criterion, PlotConfiguration, Throughput,
};

criterion_group!(
Expand Down
6 changes: 3 additions & 3 deletions benches/benches/bevy_reflect/map.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use core::{fmt::Write, iter, time::Duration};
use core::{fmt::Write, hint::black_box, iter, time::Duration};

use benches::bench;
use bevy_reflect::{DynamicMap, Map};
use bevy_utils::HashMap;
use criterion::{
black_box, criterion_group, measurement::Measurement, AxisScale, BatchSize, BenchmarkGroup,
BenchmarkId, Criterion, PlotConfiguration, Throughput,
criterion_group, measurement::Measurement, AxisScale, BatchSize, BenchmarkGroup, BenchmarkId,
Criterion, PlotConfiguration, Throughput,
};

criterion_group!(
Expand Down
4 changes: 2 additions & 2 deletions benches/benches/bevy_reflect/path.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use core::{fmt::Write, str, time::Duration};
use core::{fmt::Write, hint::black_box, str, time::Duration};

use benches::bench;
use bevy_reflect::ParsedPath;
use criterion::{black_box, criterion_group, BatchSize, BenchmarkId, Criterion, Throughput};
use criterion::{criterion_group, BatchSize, BenchmarkId, Criterion, Throughput};
use rand::{distributions::Uniform, Rng, SeedableRng};
use rand_chacha::ChaCha8Rng;

Expand Down
6 changes: 3 additions & 3 deletions benches/benches/bevy_reflect/struct.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use core::time::Duration;
use core::{hint::black_box, time::Duration};

use benches::bench;
use bevy_reflect::{DynamicStruct, GetField, PartialReflect, Reflect, Struct};
use criterion::{
black_box, criterion_group, measurement::Measurement, AxisScale, BatchSize, BenchmarkGroup,
BenchmarkId, Criterion, PlotConfiguration, Throughput,
criterion_group, measurement::Measurement, AxisScale, BatchSize, BenchmarkGroup, BenchmarkId,
Criterion, PlotConfiguration, Throughput,
};

criterion_group!(
Expand Down
4 changes: 3 additions & 1 deletion benches/benches/bevy_render/render_layers.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use criterion::{black_box, criterion_group, Criterion};
use core::hint::black_box;

use criterion::{criterion_group, Criterion};

use bevy_render::view::RenderLayers;

Expand Down
4 changes: 3 additions & 1 deletion benches/benches/bevy_render/torus.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use criterion::{black_box, criterion_group, Criterion};
use core::hint::black_box;

use criterion::{criterion_group, Criterion};

use bevy_render::mesh::TorusMeshBuilder;

Expand Down
4 changes: 3 additions & 1 deletion benches/benches/bevy_tasks/iter.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use core::hint::black_box;

use bevy_tasks::{ParallelIterator, TaskPoolBuilder};
use criterion::{black_box, criterion_group, BenchmarkId, Criterion};
use criterion::{criterion_group, BenchmarkId, Criterion};

struct ParChunks<'a, T>(core::slice::Chunks<'a, T>);
impl<'a, T> ParallelIterator<core::slice::Iter<'a, T>> for ParChunks<'a, T>
Expand Down
1 change: 1 addition & 0 deletions clippy.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,5 @@ disallowed-methods = [
{ path = "f32::asinh", reason = "use bevy_math::ops::asinh instead for libm determinism" },
{ path = "f32::acosh", reason = "use bevy_math::ops::acosh instead for libm determinism" },
{ path = "f32::atanh", reason = "use bevy_math::ops::atanh instead for libm determinism" },
{ path = "criterion::black_box", reason = "use core::hint::black_box instead" },
]

0 comments on commit 17ad855

Please sign in to comment.