benchmark_api.h revision c7ab1b987ba9badeda367145b2e2073fc0ed0d57
1// Support for registering benchmarks for functions.
2
3/* Example usage:
4// Define a function that executes the code to be measured a
5// specified number of times:
6static void BM_StringCreation(benchmark::State& state) {
7  while (state.KeepRunning())
8    std::string empty_string;
9}
10
11// Register the function as a benchmark
12BENCHMARK(BM_StringCreation);
13
14// Define another benchmark
15static void BM_StringCopy(benchmark::State& state) {
16  std::string x = "hello";
17  while (state.KeepRunning())
18    std::string copy(x);
19}
20BENCHMARK(BM_StringCopy);
21
22// Augment the main() program to invoke benchmarks if specified
23// via the --benchmarks command line flag.  E.g.,
24//       my_unittest --benchmark_filter=all
25//       my_unittest --benchmark_filter=BM_StringCreation
26//       my_unittest --benchmark_filter=String
27//       my_unittest --benchmark_filter='Copy|Creation'
28int main(int argc, char** argv) {
29  benchmark::Initialize(&argc, argv);
30  benchmark::RunSpecifiedBenchmarks();
31  return 0;
32}
33
34// Sometimes a family of microbenchmarks can be implemented with
35// just one routine that takes an extra argument to specify which
36// one of the family of benchmarks to run.  For example, the following
37// code defines a family of microbenchmarks for measuring the speed
38// of memcpy() calls of different lengths:
39
40static void BM_memcpy(benchmark::State& state) {
41  char* src = new char[state.range_x()]; char* dst = new char[state.range_x()];
42  memset(src, 'x', state.range_x());
43  while (state.KeepRunning())
44    memcpy(dst, src, state.range_x());
45  state.SetBytesProcessed(int64_t(state.iterations()) *
46                          int64_t(state.range_x()));
47  delete[] src; delete[] dst;
48}
49BENCHMARK(BM_memcpy)->Arg(8)->Arg(64)->Arg(512)->Arg(1<<10)->Arg(8<<10);
50
51// The preceding code is quite repetitive, and can be replaced with the
52// following short-hand.  The following invocation will pick a few
53// appropriate arguments in the specified range and will generate a
54// microbenchmark for each such argument.
55BENCHMARK(BM_memcpy)->Range(8, 8<<10);
56
57// You might have a microbenchmark that depends on two inputs.  For
58// example, the following code defines a family of microbenchmarks for
59// measuring the speed of set insertion.
60static void BM_SetInsert(benchmark::State& state) {
61  while (state.KeepRunning()) {
62    state.PauseTiming();
63    set<int> data = ConstructRandomSet(state.range_x());
64    state.ResumeTiming();
65    for (int j = 0; j < state.range_y(); ++j)
66      data.insert(RandomNumber());
67  }
68}
69BENCHMARK(BM_SetInsert)
70   ->ArgPair(1<<10, 1)
71   ->ArgPair(1<<10, 8)
72   ->ArgPair(1<<10, 64)
73   ->ArgPair(1<<10, 512)
74   ->ArgPair(8<<10, 1)
75   ->ArgPair(8<<10, 8)
76   ->ArgPair(8<<10, 64)
77   ->ArgPair(8<<10, 512);
78
79// The preceding code is quite repetitive, and can be replaced with
80// the following short-hand.  The following macro will pick a few
81// appropriate arguments in the product of the two specified ranges
82// and will generate a microbenchmark for each such pair.
83BENCHMARK(BM_SetInsert)->RangePair(1<<10, 8<<10, 1, 512);
84
85// For more complex patterns of inputs, passing a custom function
86// to Apply allows programmatic specification of an
87// arbitrary set of arguments to run the microbenchmark on.
88// The following example enumerates a dense range on
89// one parameter, and a sparse range on the second.
90static void CustomArguments(benchmark::internal::Benchmark* b) {
91  for (int i = 0; i <= 10; ++i)
92    for (int j = 32; j <= 1024*1024; j *= 8)
93      b->ArgPair(i, j);
94}
95BENCHMARK(BM_SetInsert)->Apply(CustomArguments);
96
97// Templated microbenchmarks work the same way:
98// Produce then consume 'size' messages 'iters' times
99// Measures throughput in the absence of multiprogramming.
100template <class Q> int BM_Sequential(benchmark::State& state) {
101  Q q;
102  typename Q::value_type v;
103  while (state.KeepRunning()) {
104    for (int i = state.range_x(); i--; )
105      q.push(v);
106    for (int e = state.range_x(); e--; )
107      q.Wait(&v);
108  }
109  // actually messages, not bytes:
110  state.SetBytesProcessed(
111      static_cast<int64_t>(state.iterations())*state.range_x());
112}
113BENCHMARK_TEMPLATE(BM_Sequential, WaitQueue<int>)->Range(1<<0, 1<<10);
114
115Use `Benchmark::MinTime(double t)` to set the minimum time used to run the
116benchmark. This option overrides the `benchmark_min_time` flag.
117
118void BM_test(benchmark::State& state) {
119 ... body ...
120}
121BENCHMARK(BM_test)->MinTime(2.0); // Run for at least 2 seconds.
122
123In a multithreaded test, it is guaranteed that none of the threads will start
124until all have called KeepRunning, and all will have finished before KeepRunning
125returns false. As such, any global setup or teardown you want to do can be
126wrapped in a check against the thread index:
127
128static void BM_MultiThreaded(benchmark::State& state) {
129  if (state.thread_index == 0) {
130    // Setup code here.
131  }
132  while (state.KeepRunning()) {
133    // Run the test as normal.
134  }
135  if (state.thread_index == 0) {
136    // Teardown code here.
137  }
138}
139BENCHMARK(BM_MultiThreaded)->Threads(4);
140*/
141
142#ifndef BENCHMARK_BENCHMARK_API_H_
143#define BENCHMARK_BENCHMARK_API_H_
144
145#include <assert.h>
146#include <stddef.h>
147#include <stdint.h>
148
149#include "macros.h"
150
151namespace benchmark {
152class BenchmarkReporter;
153
154void Initialize(int* argc, char** argv);
155
156// Otherwise, run all benchmarks specified by the --benchmark_filter flag,
157// and exit after running the benchmarks.
158void RunSpecifiedBenchmarks();
159void RunSpecifiedBenchmarks(BenchmarkReporter* reporter);
160
161// If this routine is called, peak memory allocation past this point in the
162// benchmark is reported at the end of the benchmark report line. (It is
163// computed by running the benchmark once with a single iteration and a memory
164// tracer.)
165// TODO(dominic)
166// void MemoryUsage();
167
168namespace internal {
169class Benchmark;
170class BenchmarkImp;
171class BenchmarkFamilies;
172
173template <class T> struct Voider {
174    typedef void type;
175};
176
177template <class T, class = void>
178struct EnableIfString {};
179
180template <class T>
181struct EnableIfString<T, typename Voider<typename T::basic_string>::type> {
182    typedef int type;
183};
184
185void UseCharPointer(char const volatile*);
186
187// Take ownership of the pointer and register the benchmark. Return the
188// registered benchmark.
189Benchmark* RegisterBenchmarkInternal(Benchmark*);
190
191} // end namespace internal
192
193
194// The DoNotOptimize(...) function can be used to prevent a value or
195// expression from being optimized away by the compiler. This function is
196// intented to add little to no overhead.
197// See: http://stackoverflow.com/questions/28287064
198#if defined(__clang__) && defined(__GNUC__)
199// TODO(ericwf): Clang has a bug where it tries to always use a register
200// even if value must be stored in memory. This causes codegen to fail.
201// To work around this we remove the "r" modifier so the operand is always
202// loaded into memory.
203template <class Tp>
204inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
205    asm volatile("" : "+m" (const_cast<Tp&>(value)));
206}
207#elif defined(__GNUC__)
208template <class Tp>
209inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
210    asm volatile("" : "+rm" (const_cast<Tp&>(value)));
211}
212#else
213template <class Tp>
214inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
215    internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
216}
217#endif
218
219
220// State is passed to a running Benchmark and contains state for the
221// benchmark to use.
222class State {
223public:
224  State(size_t max_iters, bool has_x, int x, bool has_y, int y, int thread_i);
225
226  // Returns true iff the benchmark should continue through another iteration.
227  // NOTE: A benchmark may not return from the test until KeepRunning() has
228  // returned false.
229  bool KeepRunning() {
230    if (BENCHMARK_BUILTIN_EXPECT(!started_, false)) {
231        ResumeTiming();
232        started_ = true;
233    }
234    bool const res = total_iterations_++ < max_iterations;
235    if (BENCHMARK_BUILTIN_EXPECT(!res, false)) {
236        assert(started_);
237        PauseTiming();
238        // Total iterations now is one greater than max iterations. Fix this.
239        total_iterations_ = max_iterations;
240    }
241    return res;
242  }
243
244  // REQUIRES: timer is running
245  // Stop the benchmark timer.  If not called, the timer will be
246  // automatically stopped after KeepRunning() returns false for the first time.
247  //
248  // For threaded benchmarks the PauseTiming() function acts
249  // like a barrier.  I.e., the ith call by a particular thread to this
250  // function will block until all threads have made their ith call.
251  // The timer will stop when the last thread has called this function.
252  //
253  // NOTE: PauseTiming()/ResumeTiming() are relatively
254  // heavyweight, and so their use should generally be avoided
255  // within each benchmark iteration, if possible.
256  void PauseTiming();
257
258  // REQUIRES: timer is not running
259  // Start the benchmark timer.  The timer is NOT running on entrance to the
260  // benchmark function. It begins running after the first call to KeepRunning()
261  //
262  // For threaded benchmarks the ResumeTiming() function acts
263  // like a barrier.  I.e., the ith call by a particular thread to this
264  // function will block until all threads have made their ith call.
265  // The timer will start when the last thread has called this function.
266  //
267  // NOTE: PauseTiming()/ResumeTiming() are relatively
268  // heavyweight, and so their use should generally be avoided
269  // within each benchmark iteration, if possible.
270  void ResumeTiming();
271
272  // Set the number of bytes processed by the current benchmark
273  // execution.  This routine is typically called once at the end of a
274  // throughput oriented benchmark.  If this routine is called with a
275  // value > 0, the report is printed in MB/sec instead of nanoseconds
276  // per iteration.
277  //
278  // REQUIRES: a benchmark has exited its KeepRunning loop.
279  BENCHMARK_ALWAYS_INLINE
280  void SetBytesProcessed(size_t bytes) {
281    bytes_processed_ = bytes;
282  }
283
284  BENCHMARK_ALWAYS_INLINE
285  size_t bytes_processed() const {
286    return bytes_processed_;
287  }
288
289  // If this routine is called with items > 0, then an items/s
290  // label is printed on the benchmark report line for the currently
291  // executing benchmark. It is typically called at the end of a processing
292  // benchmark where a processing items/second output is desired.
293  //
294  // REQUIRES: a benchmark has exited its KeepRunning loop.
295  BENCHMARK_ALWAYS_INLINE
296  void SetItemsProcessed(size_t items) {
297    items_processed_ = items;
298  }
299
300  BENCHMARK_ALWAYS_INLINE
301  size_t items_processed() const {
302    return items_processed_;
303  }
304
305  // If this routine is called, the specified label is printed at the
306  // end of the benchmark report line for the currently executing
307  // benchmark.  Example:
308  //  static void BM_Compress(int iters) {
309  //    ...
310  //    double compress = input_size / output_size;
311  //    benchmark::SetLabel(StringPrintf("compress:%.1f%%", 100.0*compression));
312  //  }
313  // Produces output that looks like:
314  //  BM_Compress   50         50   14115038  compress:27.3%
315  //
316  // REQUIRES: a benchmark has exited its KeepRunning loop.
317  void SetLabel(const char* label);
318
319  // Allow the use of std::string without actually including <string>.
320  // This function does not participate in overload resolution unless StringType
321  // has the nested typename `basic_string`. This typename should be provided
322  // as an injected class name in the case of std::string.
323  template <class StringType>
324  void SetLabel(StringType const & str,
325                typename internal::EnableIfString<StringType>::type = 1) {
326    this->SetLabel(str.c_str());
327  }
328
329  // Range arguments for this run. CHECKs if the argument has been set.
330  BENCHMARK_ALWAYS_INLINE
331  int range_x() const {
332    assert(has_range_x_);
333    ((void)has_range_x_); // Prevent unused warning.
334    return range_x_;
335  }
336
337  BENCHMARK_ALWAYS_INLINE
338  int range_y() const {
339    assert(has_range_y_);
340    ((void)has_range_y_); // Prevent unused warning.
341    return range_y_;
342  }
343
344  BENCHMARK_ALWAYS_INLINE
345  size_t iterations() const { return total_iterations_; }
346
347private:
348  bool started_;
349  size_t total_iterations_;
350
351  bool has_range_x_;
352  int range_x_;
353
354  bool has_range_y_;
355  int range_y_;
356
357  size_t bytes_processed_;
358  size_t items_processed_;
359
360public:
361  const int thread_index;
362  const size_t max_iterations;
363
364private:
365  BENCHMARK_DISALLOW_COPY_AND_ASSIGN(State);
366};
367
368namespace internal {
369
370typedef void(Function)(State&);
371
372// ------------------------------------------------------
373// Benchmark registration object.  The BENCHMARK() macro expands
374// into an internal::Benchmark* object.  Various methods can
375// be called on this object to change the properties of the benchmark.
376// Each method returns "this" so that multiple method calls can
377// chained into one expression.
378class Benchmark {
379public:
380  virtual ~Benchmark();
381
382  // Note: the following methods all return "this" so that multiple
383  // method calls can be chained together in one expression.
384
385  // Run this benchmark once with "x" as the extra argument passed
386  // to the function.
387  // REQUIRES: The function passed to the constructor must accept an arg1.
388  Benchmark* Arg(int x);
389
390  // Run this benchmark once for a number of values picked from the
391  // range [start..limit].  (start and limit are always picked.)
392  // REQUIRES: The function passed to the constructor must accept an arg1.
393  Benchmark* Range(int start, int limit);
394
395  // Run this benchmark once for every value in the range [start..limit]
396  // REQUIRES: The function passed to the constructor must accept an arg1.
397  Benchmark* DenseRange(int start, int limit);
398
399  // Run this benchmark once with "x,y" as the extra arguments passed
400  // to the function.
401  // REQUIRES: The function passed to the constructor must accept arg1,arg2.
402  Benchmark* ArgPair(int x, int y);
403
404  // Pick a set of values A from the range [lo1..hi1] and a set
405  // of values B from the range [lo2..hi2].  Run the benchmark for
406  // every pair of values in the cartesian product of A and B
407  // (i.e., for all combinations of the values in A and B).
408  // REQUIRES: The function passed to the constructor must accept arg1,arg2.
409  Benchmark* RangePair(int lo1, int hi1, int lo2, int hi2);
410
411  // Pass this benchmark object to *func, which can customize
412  // the benchmark by calling various methods like Arg, ArgPair,
413  // Threads, etc.
414  Benchmark* Apply(void (*func)(Benchmark* benchmark));
415
416  // Set the minimum amount of time to use when running this benchmark. This
417  // option overrides the `benchmark_min_time` flag.
418  Benchmark* MinTime(double t);
419
420  // If a particular benchmark is I/O bound, runs multiple threads internally or
421  // if for some reason CPU timings are not representative, call this method. If
422  // called, the elapsed time will be used to control how many iterations are
423  // run, and in the printing of items/second or MB/seconds values.  If not
424  // called, the cpu time used by the benchmark will be used.
425  Benchmark* UseRealTime();
426
427  // Support for running multiple copies of the same benchmark concurrently
428  // in multiple threads.  This may be useful when measuring the scaling
429  // of some piece of code.
430
431  // Run one instance of this benchmark concurrently in t threads.
432  Benchmark* Threads(int t);
433
434  // Pick a set of values T from [min_threads,max_threads].
435  // min_threads and max_threads are always included in T.  Run this
436  // benchmark once for each value in T.  The benchmark run for a
437  // particular value t consists of t threads running the benchmark
438  // function concurrently.  For example, consider:
439  //    BENCHMARK(Foo)->ThreadRange(1,16);
440  // This will run the following benchmarks:
441  //    Foo in 1 thread
442  //    Foo in 2 threads
443  //    Foo in 4 threads
444  //    Foo in 8 threads
445  //    Foo in 16 threads
446  Benchmark* ThreadRange(int min_threads, int max_threads);
447
448  // Equivalent to ThreadRange(NumCPUs(), NumCPUs())
449  Benchmark* ThreadPerCpu();
450
451  virtual void Run(State& state) = 0;
452
453  // Used inside the benchmark implementation
454  struct Instance;
455
456protected:
457  explicit Benchmark(const char* name);
458  Benchmark(Benchmark const&);
459  void SetName(const char* name);
460
461private:
462  friend class BenchmarkFamilies;
463  BenchmarkImp* imp_;
464
465  Benchmark& operator=(Benchmark const&);
466};
467
468// The class used to hold all Benchmarks created from static function.
469// (ie those created using the BENCHMARK(...) macros.
470class FunctionBenchmark : public Benchmark {
471public:
472    FunctionBenchmark(const char* name, Function* func)
473        : Benchmark(name), func_(func)
474    {}
475
476    virtual void Run(State& st);
477private:
478    Function* func_;
479};
480
481}  // end namespace internal
482
483// The base class for all fixture tests.
484class Fixture: public internal::Benchmark {
485public:
486    Fixture() : internal::Benchmark("") {}
487
488    virtual void Run(State& st) {
489      this->SetUp();
490      this->BenchmarkCase(st);
491      this->TearDown();
492    }
493
494    virtual void SetUp() {}
495    virtual void TearDown() {}
496
497protected:
498    virtual void BenchmarkCase(State&) = 0;
499};
500
501}  // end namespace benchmark
502
503
504// ------------------------------------------------------
505// Macro to register benchmarks
506
507// Check that __COUNTER__ is defined and that __COUNTER__ increases by 1
508// every time it is expanded. X + 1 == X + 0 is used in case X is defined to be
509// empty. If X is empty the expression becomes (+1 == +0).
510#if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0)
511#define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__
512#else
513#define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__
514#endif
515
516// Helpers for generating unique variable names
517#define BENCHMARK_PRIVATE_NAME(n) \
518    BENCHMARK_PRIVATE_CONCAT(_benchmark_, BENCHMARK_PRIVATE_UNIQUE_ID, n)
519#define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c)
520#define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c
521
522#define BENCHMARK_PRIVATE_DECLARE(n)       \
523  static ::benchmark::internal::Benchmark* \
524  BENCHMARK_PRIVATE_NAME(n) BENCHMARK_UNUSED
525
526#define BENCHMARK(n) \
527    BENCHMARK_PRIVATE_DECLARE(n) =                               \
528        (::benchmark::internal::RegisterBenchmarkInternal(       \
529            new ::benchmark::internal::FunctionBenchmark(#n, n)))
530
531// Old-style macros
532#define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a))
533#define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->ArgPair((a1), (a2))
534#define BENCHMARK_RANGE(n, lo, hi) BENCHMARK(n)->Range((lo), (hi))
535#define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \
536  BENCHMARK(n)->RangePair((l1), (h1), (l2), (h2))
537
538// This will register a benchmark for a templatized function.  For example:
539//
540// template<int arg>
541// void BM_Foo(int iters);
542//
543// BENCHMARK_TEMPLATE(BM_Foo, 1);
544//
545// will register BM_Foo<1> as a benchmark.
546#define BENCHMARK_TEMPLATE1(n, a) \
547  BENCHMARK_PRIVATE_DECLARE(n) =  \
548      (::benchmark::internal::RegisterBenchmarkInternal( \
549        new ::benchmark::internal::FunctionBenchmark(#n "<" #a ">", n<a>)))
550
551#define BENCHMARK_TEMPLATE2(n, a, b)                     \
552  BENCHMARK_PRIVATE_DECLARE(n) =                         \
553      (::benchmark::internal::RegisterBenchmarkInternal( \
554        new ::benchmark::internal::FunctionBenchmark(    \
555            #n "<" #a "," #b ">", n<a, b>)))
556
557#if __cplusplus >= 201103L
558#define BENCHMARK_TEMPLATE(n, ...)           \
559  BENCHMARK_PRIVATE_DECLARE(n) =             \
560      (::benchmark::internal::RegisterBenchmarkInternal( \
561        new ::benchmark::internal::FunctionBenchmark( \
562        #n "<" #__VA_ARGS__ ">", n<__VA_ARGS__>)))
563#else
564#define BENCHMARK_TEMPLATE(n, a) BENCHMARK_TEMPLATE1(n, a)
565#endif
566
567
568#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method)      \
569class BaseClass##_##Method##_Benchmark : public BaseClass { \
570public:                                                     \
571    BaseClass##_##Method##_Benchmark() : BaseClass() {      \
572        this->SetName(#BaseClass "/" #Method);}             \
573protected:                                                  \
574    virtual void BenchmarkCase(::benchmark::State&);        \
575};
576
577#define BENCHMARK_DEFINE_F(BaseClass, Method) \
578    BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
579    void BaseClass##_##Method##_Benchmark::BenchmarkCase
580
581#define BENCHMARK_REGISTER_F(BaseClass, Method) \
582    BENCHMARK_PRIVATE_REGISTER_F(BaseClass##_##Method##_Benchmark)
583
584#define BENCHMARK_PRIVATE_REGISTER_F(TestName) \
585    BENCHMARK_PRIVATE_DECLARE(TestName) = \
586        (::benchmark::internal::RegisterBenchmarkInternal(new TestName()))
587
588// This macro will define and register a benchmark within a fixture class.
589#define BENCHMARK_F(BaseClass, Method) \
590    BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
591    BENCHMARK_REGISTER_F(BaseClass, Method); \
592    void BaseClass##_##Method##_Benchmark::BenchmarkCase
593
594
595// Helper macro to create a main routine in a test that runs the benchmarks
596#define BENCHMARK_MAIN()                   \
597  int main(int argc, char** argv) {        \
598    ::benchmark::Initialize(&argc, argv);  \
599    ::benchmark::RunSpecifiedBenchmarks(); \
600  }
601
602#endif  // BENCHMARK_BENCHMARK_API_H_
603