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