pub fn run_under_contention<AntagonistResult, BenchmarkResult>(
    antagonist: impl FnMut() -> AntagonistResult + Send,
    benchmark: impl FnMut() -> BenchmarkResult
) -> BenchmarkResult
Expand description

Perform some operation while another is running in a loop in another thread

For multithreaded code, benchmarking the performance of isolated operations is usually only half of the story. Synchronization and memory contention can also have a large impact on performance.

For this reason, it is often useful to also measure the performance of one operation as another “antagonist” operation is also running in a background thread. This function helps you with setting up such an antagonist thread.

Note that the antagonist function must be designed in such a way as not to be optimized out by the compiler when run in a tight loop. Here are some ways to do this:

  • You can hide the fact that the code is run in a loop by preventing the compiler from inlining it there, see this crate’s noinline::call_mut().
  • You can obscure the fact that inputs are always the same and outputs are are not used by using core::hint::black_box() on nightly Rust, or its emulation by the Criterion benchmarking crate.
  • You can generate inputs that the compiler cannot guess using a random number generator, and use your outputs by sending them through some sort of reduction function (sum, min, max…) and checking the result.