Skip to content

Commit 2d156a1

Browse files
committed
Split measurement of walltime and perf. counters
1 parent 039bf15 commit 2d156a1

File tree

2 files changed

+19
-17
lines changed

2 files changed

+19
-17
lines changed

collector/benchlib/src/benchmark.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,13 @@ impl BenchmarkSuite {
3434

3535
/// Registers a single benchmark.
3636
/// `func` should return a closure that will be benchmarked.
37-
pub fn register<F: Fn() -> Bench + 'static, R, Bench: FnOnce() -> R + 'static>(
37+
pub fn register<F: Fn() -> Bench + Clone + 'static, R, Bench: FnOnce() -> R + 'static>(
3838
&mut self,
3939
name: &'static str,
40-
func: F,
40+
constructor: F,
4141
) {
42-
// We want to monomorphize the target `func` and then wrap it in a Box, to avoid going
43-
// through a vtable when we execute the benchmarked function.
44-
let benchmark_func = Box::new(move || {
45-
let bench_fn = func();
46-
benchmark_function(name, bench_fn)
47-
});
42+
// We want to type-erase the target `func` by wrapping it in a Box.
43+
let benchmark_func = Box::new(move || benchmark_function(name, constructor.clone()));
4844
let benchmark_def = BenchmarkWrapper {
4945
func: benchmark_func,
5046
};

collector/benchlib/src/measure/perf_counter/unix.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,39 @@ struct Counters {
1212
cache_references: Counter,
1313
}
1414

15-
/// Benchmarks a single function.
16-
pub fn benchmark_function<F: FnOnce() -> R, R>(
15+
/// Benchmarks a single function generated by `benchmark_constructor`.
16+
pub fn benchmark_function<F: Fn() -> Bench + 'static, R, Bench: FnOnce() -> R + 'static>(
1717
name: &'static str,
18-
func: F,
18+
benchmark_constructor: F,
1919
) -> anyhow::Result<BenchmarkResult> {
2020
let mut group = create_group()?;
2121
let counters = prepare_counters(&mut group)?;
2222

23-
// FIXME: don't run perf counters and time measurements together, run the benchmark twice
24-
// instead.
25-
let start = Instant::now();
23+
// Measure perf. counters.
24+
let func = benchmark_constructor();
2625

2726
// Do not act on the return value to avoid including the branch in the measurement
2827
let enable_ret = group.enable();
2928
let output = func();
3029
group.disable()?;
3130

32-
let duration = start.elapsed();
31+
// Try to avoid optimizing the result out
32+
black_box(output);
3333

3434
// Check if we have succeeded before
3535
enable_ret?;
3636

37+
let measurement = group.read()?;
38+
39+
// Measure wall time.
40+
let func = benchmark_constructor();
41+
42+
let start = Instant::now();
43+
let output = func();
44+
let duration = start.elapsed();
3745
// Try to avoid optimizing the result out
3846
black_box(output);
3947

40-
let measurement = group.read()?;
41-
4248
let result = BenchmarkResult {
4349
name: String::from(name),
4450
cycles: measurement[&counters.cycles],

0 commit comments

Comments
 (0)