1d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// Support for registering benchmarks for functions. 2d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 3d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier/* Example usage: 4d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// Define a function that executes the code to be measured a 5d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// specified number of times: 6d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierstatic void BM_StringCreation(benchmark::State& state) { 7d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier while (state.KeepRunning()) 8d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier std::string empty_string; 9d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier} 10d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 11d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// Register the function as a benchmark 12d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric FiselierBENCHMARK(BM_StringCreation); 13d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 14d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// Define another benchmark 15d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierstatic void BM_StringCopy(benchmark::State& state) { 16d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier std::string x = "hello"; 17d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier while (state.KeepRunning()) 18d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier std::string copy(x); 19d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier} 20d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric FiselierBENCHMARK(BM_StringCopy); 21d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 22d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// Augment the main() program to invoke benchmarks if specified 23d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// via the --benchmarks command line flag. E.g., 24d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// my_unittest --benchmark_filter=all 25d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// my_unittest --benchmark_filter=BM_StringCreation 26d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// my_unittest --benchmark_filter=String 27d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// my_unittest --benchmark_filter='Copy|Creation' 28d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierint main(int argc, char** argv) { 29d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier benchmark::Initialize(&argc, argv); 30d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier benchmark::RunSpecifiedBenchmarks(); 31d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier return 0; 32d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier} 33d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 34d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// Sometimes a family of microbenchmarks can be implemented with 35d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// just one routine that takes an extra argument to specify which 36d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// one of the family of benchmarks to run. For example, the following 37d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// code defines a family of microbenchmarks for measuring the speed 38d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// of memcpy() calls of different lengths: 39d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 40d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierstatic void BM_memcpy(benchmark::State& state) { 4130b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier char* src = new char[state.range(0)]; char* dst = new char[state.range(0)]; 4230b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier memset(src, 'x', state.range(0)); 43d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier while (state.KeepRunning()) 4430b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier memcpy(dst, src, state.range(0)); 45d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier state.SetBytesProcessed(int64_t(state.iterations()) * 4630b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier int64_t(state.range(0))); 47d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier delete[] src; delete[] dst; 48d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier} 49d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric FiselierBENCHMARK(BM_memcpy)->Arg(8)->Arg(64)->Arg(512)->Arg(1<<10)->Arg(8<<10); 50d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 51d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// The preceding code is quite repetitive, and can be replaced with the 52d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// following short-hand. The following invocation will pick a few 53d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// appropriate arguments in the specified range and will generate a 54d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// microbenchmark for each such argument. 55d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric FiselierBENCHMARK(BM_memcpy)->Range(8, 8<<10); 56d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 57d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// You might have a microbenchmark that depends on two inputs. For 58d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// example, the following code defines a family of microbenchmarks for 59d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// measuring the speed of set insertion. 60d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierstatic void BM_SetInsert(benchmark::State& state) { 61d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier while (state.KeepRunning()) { 62d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier state.PauseTiming(); 6330b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier set<int> data = ConstructRandomSet(state.range(0)); 64d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier state.ResumeTiming(); 6530b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier for (int j = 0; j < state.range(1); ++j) 66d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier data.insert(RandomNumber()); 67d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier } 68d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier} 69d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric FiselierBENCHMARK(BM_SetInsert) 7030b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier ->Args({1<<10, 1}) 7130b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier ->Args({1<<10, 8}) 7230b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier ->Args({1<<10, 64}) 7330b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier ->Args({1<<10, 512}) 7430b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier ->Args({8<<10, 1}) 7530b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier ->Args({8<<10, 8}) 7630b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier ->Args({8<<10, 64}) 7730b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier ->Args({8<<10, 512}); 78d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 79d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// The preceding code is quite repetitive, and can be replaced with 80d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// the following short-hand. The following macro will pick a few 81d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// appropriate arguments in the product of the two specified ranges 82d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// and will generate a microbenchmark for each such pair. 8330b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric FiselierBENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {1, 512}}); 84d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 85d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// For more complex patterns of inputs, passing a custom function 86d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// to Apply allows programmatic specification of an 87d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// arbitrary set of arguments to run the microbenchmark on. 88d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// The following example enumerates a dense range on 89d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// one parameter, and a sparse range on the second. 90d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierstatic void CustomArguments(benchmark::internal::Benchmark* b) { 91d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier for (int i = 0; i <= 10; ++i) 92d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier for (int j = 32; j <= 1024*1024; j *= 8) 9330b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier b->Args({i, j}); 94d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier} 95d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric FiselierBENCHMARK(BM_SetInsert)->Apply(CustomArguments); 96d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 97d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// Templated microbenchmarks work the same way: 98d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// Produce then consume 'size' messages 'iters' times 99d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// Measures throughput in the absence of multiprogramming. 100d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiseliertemplate <class Q> int BM_Sequential(benchmark::State& state) { 101d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier Q q; 102d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier typename Q::value_type v; 103d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier while (state.KeepRunning()) { 10430b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier for (int i = state.range(0); i--; ) 105d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier q.push(v); 10630b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier for (int e = state.range(0); e--; ) 107d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier q.Wait(&v); 108d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier } 109d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // actually messages, not bytes: 110d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier state.SetBytesProcessed( 11130b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier static_cast<int64_t>(state.iterations())*state.range(0)); 112d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier} 113d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric FiselierBENCHMARK_TEMPLATE(BM_Sequential, WaitQueue<int>)->Range(1<<0, 1<<10); 114d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 115d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric FiselierUse `Benchmark::MinTime(double t)` to set the minimum time used to run the 116d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierbenchmark. This option overrides the `benchmark_min_time` flag. 117d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 118d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiseliervoid BM_test(benchmark::State& state) { 119d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier ... body ... 120d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier} 121d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric FiselierBENCHMARK(BM_test)->MinTime(2.0); // Run for at least 2 seconds. 122d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 123d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric FiselierIn a multithreaded test, it is guaranteed that none of the threads will start 124d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselieruntil all have called KeepRunning, and all will have finished before KeepRunning 125d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierreturns false. As such, any global setup or teardown you want to do can be 126d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierwrapped in a check against the thread index: 127d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 128d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierstatic void BM_MultiThreaded(benchmark::State& state) { 129d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier if (state.thread_index == 0) { 130d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Setup code here. 131d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier } 132d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier while (state.KeepRunning()) { 133d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Run the test as normal. 134d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier } 135d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier if (state.thread_index == 0) { 136d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Teardown code here. 137d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier } 138d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier} 139d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric FiselierBENCHMARK(BM_MultiThreaded)->Threads(4); 140d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 141d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 142d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric FiselierIf a benchmark runs a few milliseconds it may be hard to visually compare the 143d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiseliermeasured times, since the output data is given in nanoseconds per default. In 144d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierorder to manually set the time unit, you can specify it manually: 145d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 146d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric FiselierBENCHMARK(BM_test)->Unit(benchmark::kMillisecond); 147d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier*/ 148d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 149d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#ifndef BENCHMARK_BENCHMARK_API_H_ 150d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#define BENCHMARK_BENCHMARK_API_H_ 151d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 152d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#include <assert.h> 153d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#include <stddef.h> 154d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#include <stdint.h> 155d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 156d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier#include <string> 15730b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier#include <vector> 15830b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier 159d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#include "macros.h" 160d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 16130b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier#if defined(BENCHMARK_HAS_CXX11) 16230b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier#include <type_traits> 16330b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier#include <utility> 16430b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier#endif 16530b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier 166d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiseliernamespace benchmark { 167d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierclass BenchmarkReporter; 168d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 169d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiseliervoid Initialize(int* argc, char** argv); 170d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 171d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// Generate a list of benchmarks matching the specified --benchmark_filter flag 172d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// and if --benchmark_list_tests is specified return after printing the name 173d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// of each matching benchmark. Otherwise run each matching benchmark and 174d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// report the results. 175d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// 17630b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier// The second and third overload use the specified 'console_reporter' and 177d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier// 'file_reporter' respectively. 'file_reporter' will write to the file 178d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier// specified 17930b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier// by '--benchmark_output'. If '--benchmark_output' is not given the 18030b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier// 'file_reporter' is ignored. 181d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// 182d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// RETURNS: The number of matching benchmarks. 183d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiseliersize_t RunSpecifiedBenchmarks(); 18430b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiseliersize_t RunSpecifiedBenchmarks(BenchmarkReporter* console_reporter); 18530b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiseliersize_t RunSpecifiedBenchmarks(BenchmarkReporter* console_reporter, 18630b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier BenchmarkReporter* file_reporter); 187d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 188d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// If this routine is called, peak memory allocation past this point in the 189d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// benchmark is reported at the end of the benchmark report line. (It is 190d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// computed by running the benchmark once with a single iteration and a memory 191d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// tracer.) 192d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// TODO(dominic) 193d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// void MemoryUsage(); 194d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 195d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiseliernamespace internal { 196d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierclass Benchmark; 197d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierclass BenchmarkImp; 198d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierclass BenchmarkFamilies; 199d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 200d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiseliertemplate <class T> 201d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselierstruct Voider { 202d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier typedef void type; 203d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier}; 204d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 205d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiseliertemplate <class T, class = void> 206d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierstruct EnableIfString {}; 207d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 208d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiseliertemplate <class T> 209d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierstruct EnableIfString<T, typename Voider<typename T::basic_string>::type> { 210d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier typedef int type; 211d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier}; 212d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 213d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiseliervoid UseCharPointer(char const volatile*); 214d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 215d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// Take ownership of the pointer and register the benchmark. Return the 216d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// registered benchmark. 217d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric FiselierBenchmark* RegisterBenchmarkInternal(Benchmark*); 218d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 219f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier// Ensure that the standard streams are properly initialized in every TU. 220f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselierint InitializeStreams(); 221f76a08728e783fea3a9204a6f85f5a622a48552dEric FiselierBENCHMARK_UNUSED static int stream_init_anchor = InitializeStreams(); 222f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier 223d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier} // end namespace internal 224d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 225d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// The DoNotOptimize(...) function can be used to prevent a value or 226d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// expression from being optimized away by the compiler. This function is 227d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// intended to add little to no overhead. 228d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// See: https://youtu.be/nXaxk27zwlk?t=2441 229d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#if defined(__GNUC__) 230d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiseliertemplate <class Tp> 231d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierinline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) { 232d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier asm volatile("" : : "g"(value) : "memory"); 233d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier} 234d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// Force the compiler to flush pending writes to global memory. Acts as an 235d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// effective read/write barrier 236d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierinline BENCHMARK_ALWAYS_INLINE void ClobberMemory() { 237d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier asm volatile("" : : : "memory"); 238d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier} 239d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#else 240d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiseliertemplate <class Tp> 241d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierinline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) { 242d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value)); 243d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier} 244d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// FIXME Add ClobberMemory() for non-gnu compilers 245d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#endif 246d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 247d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// TimeUnit is passed to a benchmark in order to specify the order of magnitude 248d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// for the measured time. 249d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselierenum TimeUnit { kNanosecond, kMicrosecond, kMillisecond }; 250d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 251d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier// BigO is passed to a benchmark in order to specify the asymptotic 252d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier// computational 253d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier// complexity for the benchmark. In case oAuto is selected, complexity will be 254d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// calculated automatically to the best fit. 255d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselierenum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLambda }; 256d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 257d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier// BigOFunc is passed to a benchmark in order to specify the asymptotic 258d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// computational complexity for the benchmark. 259d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiseliertypedef double(BigOFunc)(int); 260d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 261d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiseliernamespace internal { 262d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselierclass ThreadTimer; 263d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselierclass ThreadManager; 264d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier 265d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier#if defined(BENCHMARK_HAS_CXX11) 266d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselierenum ReportMode : unsigned { 267d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier#else 268d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselierenum ReportMode { 269d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier#endif 270d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier RM_Unspecified, // The mode has not been manually specified 271d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier RM_Default, // The mode is user-specified as default. 272d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier RM_ReportAggregatesOnly 273d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier}; 274d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier} 275d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier 276d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// State is passed to a running Benchmark and contains state for the 277d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// benchmark to use. 278d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierclass State { 279d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier public: 280d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Returns true if the benchmark should continue through another iteration. 281d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // NOTE: A benchmark may not return from the test until KeepRunning() has 282d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // returned false. 283d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier bool KeepRunning() { 284d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier if (BENCHMARK_BUILTIN_EXPECT(!started_, false)) { 285d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier StartKeepRunning(); 286d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier } 287d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier bool const res = total_iterations_++ < max_iterations; 288d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier if (BENCHMARK_BUILTIN_EXPECT(!res, false)) { 289d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier FinishKeepRunning(); 290d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier } 291d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier return res; 292d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier } 293d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 294d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // REQUIRES: timer is running and 'SkipWithError(...)' has not been called 295d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // by the current thread. 296d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Stop the benchmark timer. If not called, the timer will be 297d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // automatically stopped after KeepRunning() returns false for the first time. 298d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // 299d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // For threaded benchmarks the PauseTiming() function only pauses the timing 300d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // for the current thread. 301d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // 302d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // NOTE: The "real time" measurement is per-thread. If different threads 303d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // report different measurements the largest one is reported. 304d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // 305d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // NOTE: PauseTiming()/ResumeTiming() are relatively 306d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // heavyweight, and so their use should generally be avoided 307d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // within each benchmark iteration, if possible. 308d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier void PauseTiming(); 309d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 310d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // REQUIRES: timer is not running and 'SkipWithError(...)' has not been called 311d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // by the current thread. 312d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Start the benchmark timer. The timer is NOT running on entrance to the 313d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // benchmark function. It begins running after the first call to KeepRunning() 314d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // 315d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // NOTE: PauseTiming()/ResumeTiming() are relatively 316d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // heavyweight, and so their use should generally be avoided 317d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // within each benchmark iteration, if possible. 318d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier void ResumeTiming(); 319d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 320d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // REQUIRES: 'SkipWithError(...)' has not been called previously by the 321d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // current thread. 322d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Skip any future iterations of the 'KeepRunning()' loop in the current 323d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // thread and report an error with the specified 'msg'. After this call 324d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // the user may explicitly 'return' from the benchmark. 325d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // 326d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // For threaded benchmarks only the current thread stops executing and future 327d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // calls to `KeepRunning()` will block until all threads have completed 328d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // the `KeepRunning()` loop. If multiple threads report an error only the 329d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // first error message is used. 330d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // 331d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // NOTE: Calling 'SkipWithError(...)' does not cause the benchmark to exit 332d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // the current scope immediately. If the function is called from within 333d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // the 'KeepRunning()' loop the current iteration will finish. It is the users 334d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // responsibility to exit the scope as needed. 335d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier void SkipWithError(const char* msg); 336d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 337d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // REQUIRES: called exactly once per iteration of the KeepRunning loop. 338d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Set the manually measured time for this benchmark iteration, which 339d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // is used instead of automatically measured time if UseManualTime() was 340d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // specified. 341d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // 342d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // For threaded benchmarks the final value will be set to the largest 343d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // reported values. 344d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier void SetIterationTime(double seconds); 345d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 346d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Set the number of bytes processed by the current benchmark 347d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // execution. This routine is typically called once at the end of a 348d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // throughput oriented benchmark. If this routine is called with a 349d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // value > 0, the report is printed in MB/sec instead of nanoseconds 350d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // per iteration. 351d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // 352d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // REQUIRES: a benchmark has exited its KeepRunning loop. 353d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier BENCHMARK_ALWAYS_INLINE 354d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier void SetBytesProcessed(size_t bytes) { bytes_processed_ = bytes; } 355d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 356d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier BENCHMARK_ALWAYS_INLINE 357d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier size_t bytes_processed() const { return bytes_processed_; } 358d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 359d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // If this routine is called with complexity_n > 0 and complexity report is 360d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // requested for the 361d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // family benchmark, then current benchmark will be part of the computation 362d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // and complexity_n will 363d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // represent the length of N. 364d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier BENCHMARK_ALWAYS_INLINE 365d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier void SetComplexityN(int complexity_n) { complexity_n_ = complexity_n; } 366d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 367d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier BENCHMARK_ALWAYS_INLINE 368d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier int complexity_length_n() { return complexity_n_; } 369d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 370d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // If this routine is called with items > 0, then an items/s 371d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // label is printed on the benchmark report line for the currently 372d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // executing benchmark. It is typically called at the end of a processing 373d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // benchmark where a processing items/second output is desired. 374d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // 375d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // REQUIRES: a benchmark has exited its KeepRunning loop. 376d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier BENCHMARK_ALWAYS_INLINE 377d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier void SetItemsProcessed(size_t items) { items_processed_ = items; } 378d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 379d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier BENCHMARK_ALWAYS_INLINE 380d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier size_t items_processed() const { return items_processed_; } 381d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 382d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // If this routine is called, the specified label is printed at the 383d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // end of the benchmark report line for the currently executing 384d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // benchmark. Example: 385d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // static void BM_Compress(benchmark::State& state) { 386d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // ... 387d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // double compress = input_size / output_size; 388d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // state.SetLabel(StringPrintf("compress:%.1f%%", 100.0*compression)); 389d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // } 390d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Produces output that looks like: 391d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // BM_Compress 50 50 14115038 compress:27.3% 392d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // 393d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // REQUIRES: a benchmark has exited its KeepRunning loop. 394d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier void SetLabel(const char* label); 395d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 396d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Allow the use of std::string without actually including <string>. 397d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // This function does not participate in overload resolution unless StringType 398d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // has the nested typename `basic_string`. This typename should be provided 399d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // as an injected class name in the case of std::string. 400d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier template <class StringType> 401d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier void SetLabel(StringType const& str, 402d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier typename internal::EnableIfString<StringType>::type = 1) { 403d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier this->SetLabel(str.c_str()); 404d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier } 405d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 406d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Range arguments for this run. CHECKs if the argument has been set. 407d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier BENCHMARK_ALWAYS_INLINE 408f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier int range(std::size_t pos = 0) const { 409d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier assert(range_.size() > pos); 410d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier return range_[pos]; 411d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier } 412d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 413f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier BENCHMARK_DEPRECATED_MSG("use 'range(0)' instead") 414f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier int range_x() const { return range(0); } 415f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier 416f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier BENCHMARK_DEPRECATED_MSG("use 'range(1)' instead") 417f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier int range_y() const { return range(1); } 418f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier 419d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier BENCHMARK_ALWAYS_INLINE 420d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier size_t iterations() const { return total_iterations_; } 421d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 422d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier private: 423d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier bool started_; 424d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier bool finished_; 425d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier size_t total_iterations_; 426d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 42730b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier std::vector<int> range_; 428d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 429d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier size_t bytes_processed_; 430d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier size_t items_processed_; 431d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 432d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier int complexity_n_; 433d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 434d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier bool error_occurred_; 435d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier 436d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier public: 437d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Index of the executing thread. Values from [0, threads). 438d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier const int thread_index; 439d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Number of threads concurrently executing the benchmark. 440d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier const int threads; 441d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier const size_t max_iterations; 442d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 443d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // TODO make me private 444d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier State(size_t max_iters, const std::vector<int>& ranges, int thread_i, 445d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier int n_threads, internal::ThreadTimer* timer, 446d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier internal::ThreadManager* manager); 447d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier 448d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier private: 449d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier void StartKeepRunning(); 450d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier void FinishKeepRunning(); 451d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier internal::ThreadTimer* timer_; 452d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier internal::ThreadManager* manager_; 453d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier BENCHMARK_DISALLOW_COPY_AND_ASSIGN(State); 454d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier}; 455d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 456d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiseliernamespace internal { 457d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 458d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiseliertypedef void(Function)(State&); 459d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 460d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// ------------------------------------------------------ 461d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// Benchmark registration object. The BENCHMARK() macro expands 462d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// into an internal::Benchmark* object. Various methods can 463d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// be called on this object to change the properties of the benchmark. 464d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// Each method returns "this" so that multiple method calls can 465d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// chained into one expression. 466d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierclass Benchmark { 467d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier public: 468d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier virtual ~Benchmark(); 469d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 470d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Note: the following methods all return "this" so that multiple 471d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // method calls can be chained together in one expression. 472d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 473d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Run this benchmark once with "x" as the extra argument passed 474d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // to the function. 475d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // REQUIRES: The function passed to the constructor must accept an arg1. 476d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier Benchmark* Arg(int x); 477d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 478d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Run this benchmark with the given time unit for the generated output report 479d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier Benchmark* Unit(TimeUnit unit); 480d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 481d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Run this benchmark once for a number of values picked from the 482d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // range [start..limit]. (start and limit are always picked.) 483d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // REQUIRES: The function passed to the constructor must accept an arg1. 484d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier Benchmark* Range(int start, int limit); 485d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 486d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // Run this benchmark once for all values in the range [start..limit] with 487d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // specific step 488d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // REQUIRES: The function passed to the constructor must accept an arg1. 48930b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier Benchmark* DenseRange(int start, int limit, int step = 1); 490d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 49130b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier // Run this benchmark once with "args" as the extra arguments passed 492d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // to the function. 49330b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier // REQUIRES: The function passed to the constructor must accept arg1, arg2 ... 49430b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier Benchmark* Args(const std::vector<int>& args); 495d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 496f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier // Equivalent to Args({x, y}) 497f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier // NOTE: This is a legacy C++03 interface provided for compatibility only. 498f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier // New code should use 'Args'. 499f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier Benchmark* ArgPair(int x, int y) { 500d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier std::vector<int> args; 501d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier args.push_back(x); 502d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier args.push_back(y); 503d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier return Args(args); 504f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier } 505f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier 50630b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier // Run this benchmark once for a number of values picked from the 50730b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier // ranges [start..limit]. (starts and limits are always picked.) 50830b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier // REQUIRES: The function passed to the constructor must accept arg1, arg2 ... 50930b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier Benchmark* Ranges(const std::vector<std::pair<int, int> >& ranges); 510d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 511d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // Equivalent to ArgNames({name}) 512d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier Benchmark* ArgName(const std::string& name); 513d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier 514d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // Set the argument names to display in the benchmark name. If not called, 515d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // only argument values will be shown. 516d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier Benchmark* ArgNames(const std::vector<std::string>& names); 517d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier 518f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier // Equivalent to Ranges({{lo1, hi1}, {lo2, hi2}}). 519f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier // NOTE: This is a legacy C++03 interface provided for compatibility only. 520f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier // New code should use 'Ranges'. 521f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier Benchmark* RangePair(int lo1, int hi1, int lo2, int hi2) { 522d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier std::vector<std::pair<int, int> > ranges; 523d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier ranges.push_back(std::make_pair(lo1, hi1)); 524d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier ranges.push_back(std::make_pair(lo2, hi2)); 525d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier return Ranges(ranges); 526f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier } 527f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier 528d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Pass this benchmark object to *func, which can customize 52930b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier // the benchmark by calling various methods like Arg, Args, 530d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Threads, etc. 531d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier Benchmark* Apply(void (*func)(Benchmark* benchmark)); 532d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 533d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // Set the range multiplier for non-dense range. If not called, the range 534d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // multiplier kRangeMultiplier will be used. 535d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier Benchmark* RangeMultiplier(int multiplier); 536d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 537d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Set the minimum amount of time to use when running this benchmark. This 538d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // option overrides the `benchmark_min_time` flag. 539d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // REQUIRES: `t > 0` 540d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier Benchmark* MinTime(double t); 541d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 542d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Specify the amount of times to repeat this benchmark. This option overrides 543d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // the `benchmark_repetitions` flag. 544d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // REQUIRES: `n > 0` 545d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier Benchmark* Repetitions(int n); 546d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 547f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier // Specify if each repetition of the benchmark should be reported separately 548f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier // or if only the final statistics should be reported. If the benchmark 549f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier // is not repeated then the single result is always reported. 550f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier Benchmark* ReportAggregatesOnly(bool v = true); 551f76a08728e783fea3a9204a6f85f5a622a48552dEric Fiselier 552d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // If a particular benchmark is I/O bound, runs multiple threads internally or 553d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // if for some reason CPU timings are not representative, call this method. If 554d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // called, the elapsed time will be used to control how many iterations are 555d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // run, and in the printing of items/second or MB/seconds values. If not 556d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // called, the cpu time used by the benchmark will be used. 557d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier Benchmark* UseRealTime(); 558d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 559d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // If a benchmark must measure time manually (e.g. if GPU execution time is 560d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // being 561d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // measured), call this method. If called, each benchmark iteration should 562d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // call 563d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // SetIterationTime(seconds) to report the measured time, which will be used 564d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // to control how many iterations are run, and in the printing of items/second 565d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // or MB/second values. 566d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier Benchmark* UseManualTime(); 567d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 568d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Set the asymptotic computational complexity for the benchmark. If called 569d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // the asymptotic computational complexity will be shown on the output. 570d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier Benchmark* Complexity(BigO complexity = benchmark::oAuto); 571d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 572d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Set the asymptotic computational complexity for the benchmark. If called 573d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // the asymptotic computational complexity will be shown on the output. 574d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier Benchmark* Complexity(BigOFunc* complexity); 575d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 576d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Support for running multiple copies of the same benchmark concurrently 577d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // in multiple threads. This may be useful when measuring the scaling 578d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // of some piece of code. 579d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 580d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Run one instance of this benchmark concurrently in t threads. 581d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier Benchmark* Threads(int t); 582d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 583d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Pick a set of values T from [min_threads,max_threads]. 584d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // min_threads and max_threads are always included in T. Run this 585d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // benchmark once for each value in T. The benchmark run for a 586d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // particular value t consists of t threads running the benchmark 587d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // function concurrently. For example, consider: 588d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // BENCHMARK(Foo)->ThreadRange(1,16); 589d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // This will run the following benchmarks: 590d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Foo in 1 thread 591d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Foo in 2 threads 592d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Foo in 4 threads 593d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Foo in 8 threads 594d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Foo in 16 threads 595d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier Benchmark* ThreadRange(int min_threads, int max_threads); 596d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 597d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // For each value n in the range, run this benchmark once using n threads. 598d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // min_threads and max_threads are always included in the range. 599d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // stride specifies the increment. E.g. DenseThreadRange(1, 8, 3) starts 600d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // a benchmark with 1, 4, 7 and 8 threads. 601d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier Benchmark* DenseThreadRange(int min_threads, int max_threads, int stride = 1); 602d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier 603d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Equivalent to ThreadRange(NumCPUs(), NumCPUs()) 604d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier Benchmark* ThreadPerCpu(); 605d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 606d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier virtual void Run(State& state) = 0; 607d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 608d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier // Used inside the benchmark implementation 609d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier struct Instance; 610d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 611d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier protected: 612d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier explicit Benchmark(const char* name); 613d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier Benchmark(Benchmark const&); 614d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier void SetName(const char* name); 615d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 616d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier int ArgsCnt() const; 617d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier 618d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier static void AddRange(std::vector<int>* dst, int lo, int hi, int mult); 619d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier 620d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier private: 621d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier friend class BenchmarkFamilies; 622d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier 623d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier std::string name_; 624d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier ReportMode report_mode_; 625d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier std::vector<std::string> arg_names_; // Args for all benchmark runs 626d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier std::vector<std::vector<int> > args_; // Args for all benchmark runs 627d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier TimeUnit time_unit_; 628d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier int range_multiplier_; 629d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier double min_time_; 630d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier int repetitions_; 631d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier bool use_real_time_; 632d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier bool use_manual_time_; 633d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier BigO complexity_; 634d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier BigOFunc* complexity_lambda_; 635d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier std::vector<int> thread_counts_; 636d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 637d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier Benchmark& operator=(Benchmark const&); 638d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier}; 639d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 640d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier} // namespace internal 64130b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier 64230b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier// Create and register a benchmark with the specified 'name' that invokes 64330b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier// the specified functor 'fn'. 64430b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier// 64530b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier// RETURNS: A pointer to the registered benchmark. 646d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselierinternal::Benchmark* RegisterBenchmark(const char* name, 647d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier internal::Function* fn); 64830b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier 64930b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier#if defined(BENCHMARK_HAS_CXX11) 65030b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiseliertemplate <class Lambda> 65130b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselierinternal::Benchmark* RegisterBenchmark(const char* name, Lambda&& fn); 65230b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier#endif 65330b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier 65430b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiseliernamespace internal { 655d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// The class used to hold all Benchmarks created from static function. 656d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// (ie those created using the BENCHMARK(...) macros. 657d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselierclass FunctionBenchmark : public Benchmark { 658d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier public: 659d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier FunctionBenchmark(const char* name, Function* func) 660d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier : Benchmark(name), func_(func) {} 661d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier 662d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier virtual void Run(State& st); 663d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier 664d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier private: 665d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier Function* func_; 666d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier}; 667d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 66830b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier#ifdef BENCHMARK_HAS_CXX11 66930b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiseliertemplate <class Lambda> 67030b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselierclass LambdaBenchmark : public Benchmark { 671d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier public: 672d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier virtual void Run(State& st) { lambda_(st); } 67330b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier 674d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier private: 67530b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier template <class OLambda> 67630b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier LambdaBenchmark(const char* name, OLambda&& lam) 67730b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier : Benchmark(name), lambda_(std::forward<OLambda>(lam)) {} 67830b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier 67930b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier LambdaBenchmark(LambdaBenchmark const&) = delete; 68030b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier 681d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier private: 68230b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier template <class Lam> 68330b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier friend Benchmark* ::benchmark::RegisterBenchmark(const char*, Lam&&); 68430b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier 68530b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier Lambda lambda_; 68630b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier}; 68730b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier#endif 68830b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier 689d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier} // end namespace internal 690d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 691d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselierinline internal::Benchmark* RegisterBenchmark(const char* name, 692d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier internal::Function* fn) { 693d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier return internal::RegisterBenchmarkInternal( 694d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier ::new internal::FunctionBenchmark(name, fn)); 69530b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier} 69630b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier 69730b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier#ifdef BENCHMARK_HAS_CXX11 69830b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiseliertemplate <class Lambda> 69930b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselierinternal::Benchmark* RegisterBenchmark(const char* name, Lambda&& fn) { 700d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier using BenchType = 701d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier internal::LambdaBenchmark<typename std::decay<Lambda>::type>; 702d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier return internal::RegisterBenchmarkInternal( 703d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier ::new BenchType(name, std::forward<Lambda>(fn))); 70430b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier} 70530b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier#endif 70630b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier 70730b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier#if defined(BENCHMARK_HAS_CXX11) && \ 708d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier (!defined(BENCHMARK_GCC_VERSION) || BENCHMARK_GCC_VERSION >= 409) 709d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiseliertemplate <class Lambda, class... Args> 71030b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselierinternal::Benchmark* RegisterBenchmark(const char* name, Lambda&& fn, 71130b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier Args&&... args) { 712d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier return benchmark::RegisterBenchmark( 713d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier name, [=](benchmark::State& st) { fn(st, args...); }); 71430b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier} 71530b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier#else 71630b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier#define BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK 71730b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier#endif 71830b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier 719d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// The base class for all fixture tests. 720d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselierclass Fixture : public internal::Benchmark { 721d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier public: 722d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier Fixture() : internal::Benchmark("") {} 723d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier 724d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier virtual void Run(State& st) { 725d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier this->SetUp(st); 726d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier this->BenchmarkCase(st); 727d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier this->TearDown(st); 728d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier } 729d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 730d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // These will be deprecated ... 731d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier virtual void SetUp(const State&) {} 732d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier virtual void TearDown(const State&) {} 733d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier // ... In favor of these. 734d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier virtual void SetUp(State& st) { SetUp(const_cast<const State&>(st)); } 735d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier virtual void TearDown(State& st) { TearDown(const_cast<const State&>(st)); } 736d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 737d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier protected: 738d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier virtual void BenchmarkCase(State&) = 0; 739d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier}; 740d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 741d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier} // end namespace benchmark 742d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 743d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// ------------------------------------------------------ 744d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// Macro to register benchmarks 745d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 746d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// Check that __COUNTER__ is defined and that __COUNTER__ increases by 1 747d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// every time it is expanded. X + 1 == X + 0 is used in case X is defined to be 748d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// empty. If X is empty the expression becomes (+1 == +0). 749d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0) 750d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__ 751d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#else 752d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__ 753d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#endif 754d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 755d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// Helpers for generating unique variable names 756d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#define BENCHMARK_PRIVATE_NAME(n) \ 757d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier BENCHMARK_PRIVATE_CONCAT(_benchmark_, BENCHMARK_PRIVATE_UNIQUE_ID, n) 758d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c) 759d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c 760d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 761d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier#define BENCHMARK_PRIVATE_DECLARE(n) \ 762d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier static ::benchmark::internal::Benchmark* BENCHMARK_PRIVATE_NAME(n) \ 763d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier BENCHMARK_UNUSED 764d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 765d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier#define BENCHMARK(n) \ 766d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier BENCHMARK_PRIVATE_DECLARE(n) = \ 767d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier (::benchmark::internal::RegisterBenchmarkInternal( \ 768d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier new ::benchmark::internal::FunctionBenchmark(#n, n))) 769d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 770d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// Old-style macros 771d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a)) 77230b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier#define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->Args({(a1), (a2)}) 773d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#define BENCHMARK_WITH_UNIT(n, t) BENCHMARK(n)->Unit((t)) 774d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#define BENCHMARK_RANGE(n, lo, hi) BENCHMARK(n)->Range((lo), (hi)) 775d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \ 77630b48cb1b3a0c4fcc1887259bd215ad8738d21b4Eric Fiselier BENCHMARK(n)->RangePair({{(l1), (h1)}, {(l2), (h2)}}) 777d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 778d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#if __cplusplus >= 201103L 779d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 780d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// Register a benchmark which invokes the function specified by `func` 781d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// with the additional arguments specified by `...`. 782d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// 783d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// For example: 784d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// 785d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// template <class ...ExtraArgs>` 786d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// void BM_takes_args(benchmark::State& state, ExtraArgs&&... extra_args) { 787d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// [...] 788d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier//} 789d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// /* Registers a benchmark named "BM_takes_args/int_string_test` */ 790d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// BENCHMARK_CAPTURE(BM_takes_args, int_string_test, 42, std::string("abc")); 791d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier#define BENCHMARK_CAPTURE(func, test_case_name, ...) \ 792d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier BENCHMARK_PRIVATE_DECLARE(func) = \ 793d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier (::benchmark::internal::RegisterBenchmarkInternal( \ 794d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier new ::benchmark::internal::FunctionBenchmark( \ 795d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier #func "/" #test_case_name, \ 796d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier [](::benchmark::State& st) { func(st, __VA_ARGS__); }))) 797d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 798d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier#endif // __cplusplus >= 11 799d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 800d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// This will register a benchmark for a templatized function. For example: 801d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// 802d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// template<int arg> 803d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// void BM_Foo(int iters); 804d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// 805d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// BENCHMARK_TEMPLATE(BM_Foo, 1); 806d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// 807d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// will register BM_Foo<1> as a benchmark. 808d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier#define BENCHMARK_TEMPLATE1(n, a) \ 809d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier BENCHMARK_PRIVATE_DECLARE(n) = \ 810d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier (::benchmark::internal::RegisterBenchmarkInternal( \ 811d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier new ::benchmark::internal::FunctionBenchmark(#n "<" #a ">", n<a>))) 812d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier 813d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier#define BENCHMARK_TEMPLATE2(n, a, b) \ 814d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier BENCHMARK_PRIVATE_DECLARE(n) = \ 815d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier (::benchmark::internal::RegisterBenchmarkInternal( \ 816d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier new ::benchmark::internal::FunctionBenchmark(#n "<" #a "," #b ">", \ 817d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier n<a, b>))) 818d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 819d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#if __cplusplus >= 201103L 820d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier#define BENCHMARK_TEMPLATE(n, ...) \ 821d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier BENCHMARK_PRIVATE_DECLARE(n) = \ 822d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier (::benchmark::internal::RegisterBenchmarkInternal( \ 823d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier new ::benchmark::internal::FunctionBenchmark( \ 824d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier #n "<" #__VA_ARGS__ ">", n<__VA_ARGS__>))) 825d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#else 826d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#define BENCHMARK_TEMPLATE(n, a) BENCHMARK_TEMPLATE1(n, a) 827d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#endif 828d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 829d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \ 830d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier class BaseClass##_##Method##_Benchmark : public BaseClass { \ 831d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier public: \ 832d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier BaseClass##_##Method##_Benchmark() : BaseClass() { \ 833d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier this->SetName(#BaseClass "/" #Method); \ 834d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier } \ 835d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier \ 836d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier protected: \ 837d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier virtual void BenchmarkCase(::benchmark::State&); \ 838d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier }; 839d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier 840d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier#define BENCHMARK_DEFINE_F(BaseClass, Method) \ 841d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \ 842d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier void BaseClass##_##Method##_Benchmark::BenchmarkCase 843d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 844d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#define BENCHMARK_REGISTER_F(BaseClass, Method) \ 845d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier BENCHMARK_PRIVATE_REGISTER_F(BaseClass##_##Method##_Benchmark) 846d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 847d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#define BENCHMARK_PRIVATE_REGISTER_F(TestName) \ 848d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier BENCHMARK_PRIVATE_DECLARE(TestName) = \ 849d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier (::benchmark::internal::RegisterBenchmarkInternal(new TestName())) 850d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 851d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// This macro will define and register a benchmark within a fixture class. 852d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier#define BENCHMARK_F(BaseClass, Method) \ 853d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \ 854d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier BENCHMARK_REGISTER_F(BaseClass, Method); \ 855d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier void BaseClass##_##Method##_Benchmark::BenchmarkCase 856d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 857d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier// Helper macro to create a main routine in a test that runs the benchmarks 858d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#define BENCHMARK_MAIN() \ 859d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier int main(int argc, char** argv) { \ 860d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier ::benchmark::Initialize(&argc, argv); \ 861d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier ::benchmark::RunSpecifiedBenchmarks(); \ 862d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier } 863d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier 864d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#endif // BENCHMARK_BENCHMARK_API_H_ 865