From ea4543f63a8db4504aca146ccdcc518ecee3d9be Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 19 Jan 2018 12:26:11 +0530 Subject: [PATCH 1/3] Add iter_n --- text/0000-benchmarking.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/text/0000-benchmarking.md b/text/0000-benchmarking.md index 0b008467004..7a5d426a641 100644 --- a/text/0000-benchmarking.md +++ b/text/0000-benchmarking.md @@ -107,7 +107,16 @@ fn my_benchmark(bench: Bencher) -> BenchResult { bench.iter(|| { black_box(pow(y, x)); pow(x, y) - }); + }) +} +``` + +In case you want the benchmark to run for a predetermined number of times, use `iter_n`: + +```rust +#[bench] +fn my_benchmark(bench: Bencher) -> BenchResult { + bench.iter_n(1000, || do_some_stuff()); } ``` From 914da5c5bc2e79c2e2c6289880e9746d9a5896ca Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Fri, 19 Jan 2018 10:45:02 +0100 Subject: [PATCH 2/3] specify black_box/clobber --- text/0000-benchmarking.md | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/text/0000-benchmarking.md b/text/0000-benchmarking.md index 7a5d426a641..5bc1103ee7a 100644 --- a/text/0000-benchmarking.md +++ b/text/0000-benchmarking.md @@ -120,6 +120,23 @@ fn my_benchmark(bench: Bencher) -> BenchResult { } ``` +Using `mem::clobber()` you can force the optimizer to flush all pending writes +to memory of data previously passed to `mem::black_box`: + +```rust +fn bench_vec_push_back(bench: Bencher) -> BenchResult { + let n = 100_000_000; + let mut v = Vec::with_capacity(n); + bench.iter_n(n, || { + // Allow vector data to be clobbered: + mem::black_box(v.as_ptr()); + v.push_back(42_u8); + // Forces 42 to be written back to memory: + mem::clobber(); + }) +} +``` + # Reference-level explanation [reference-level-explanation]: #reference-level-explanation @@ -129,8 +146,28 @@ Samples are [winsorized], so extreme outliers get clamped. `cargo bench` essentially takes the same flags as `cargo test`, except it has a `--bench foo` flag to select a single benchmark target. +[winsorized]: https://en.wikipedia.org/wiki/Winsorizing + +## `mem::black_box` + +```rust +pub fn black_box(x: T) -> T; +``` + +Prevents a value or the result of an expression from being optimized away by the +compiler adding as little overhead as possible. It does not prevent +optimizations on the expression generating the value in any way: the expression +might be removed entirely when the result is already known. It forces, however, +the result of the expression to be stored in either memory or a register. + +## `mem::clobber` + +```rust +pub fn clobber() -> (); +``` - [winsorized]: https://en.wikipedia.org/wiki/Winsorizing +Is a read/write barriert: it flushes pending writes to variables "escaped" with +`mem::black_box` to global memory. # Drawbacks [drawbacks]: #drawbacks From 262c26b12ead4c42d08672009806d21055c3e4a7 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Thu, 1 Feb 2018 11:40:47 +0100 Subject: [PATCH 3/3] fix typo --- text/0000-benchmarking.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-benchmarking.md b/text/0000-benchmarking.md index 5bc1103ee7a..d44388f75e5 100644 --- a/text/0000-benchmarking.md +++ b/text/0000-benchmarking.md @@ -166,7 +166,7 @@ the result of the expression to be stored in either memory or a register. pub fn clobber() -> (); ``` -Is a read/write barriert: it flushes pending writes to variables "escaped" with +Is a read/write barrier: it flushes pending writes to variables "escaped" with `mem::black_box` to global memory. # Drawbacks