benchmark 1.7.0
Loading...
Searching...
No Matches
benchmark.h
1// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Support for registering benchmarks for functions.
16
17/* Example usage:
18// Define a function that executes the code to be measured a
19// specified number of times:
20static void BM_StringCreation(benchmark::State& state) {
21 for (auto _ : state)
22 std::string empty_string;
23}
24
25// Register the function as a benchmark
26BENCHMARK(BM_StringCreation);
27
28// Define another benchmark
29static void BM_StringCopy(benchmark::State& state) {
30 std::string x = "hello";
31 for (auto _ : state)
32 std::string copy(x);
33}
34BENCHMARK(BM_StringCopy);
35
36// Augment the main() program to invoke benchmarks if specified
37// via the --benchmark_filter command line flag. E.g.,
38// my_unittest --benchmark_filter=all
39// my_unittest --benchmark_filter=BM_StringCreation
40// my_unittest --benchmark_filter=String
41// my_unittest --benchmark_filter='Copy|Creation'
42int main(int argc, char** argv) {
43 benchmark::Initialize(&argc, argv);
44 benchmark::RunSpecifiedBenchmarks();
45 benchmark::Shutdown();
46 return 0;
47}
48
49// Sometimes a family of microbenchmarks can be implemented with
50// just one routine that takes an extra argument to specify which
51// one of the family of benchmarks to run. For example, the following
52// code defines a family of microbenchmarks for measuring the speed
53// of memcpy() calls of different lengths:
54
55static void BM_memcpy(benchmark::State& state) {
56 char* src = new char[state.range(0)]; char* dst = new char[state.range(0)];
57 memset(src, 'x', state.range(0));
58 for (auto _ : state)
59 memcpy(dst, src, state.range(0));
60 state.SetBytesProcessed(state.iterations() * state.range(0));
61 delete[] src; delete[] dst;
62}
63BENCHMARK(BM_memcpy)->Arg(8)->Arg(64)->Arg(512)->Arg(1<<10)->Arg(8<<10);
64
65// The preceding code is quite repetitive, and can be replaced with the
66// following short-hand. The following invocation will pick a few
67// appropriate arguments in the specified range and will generate a
68// microbenchmark for each such argument.
69BENCHMARK(BM_memcpy)->Range(8, 8<<10);
70
71// You might have a microbenchmark that depends on two inputs. For
72// example, the following code defines a family of microbenchmarks for
73// measuring the speed of set insertion.
74static void BM_SetInsert(benchmark::State& state) {
75 set<int> data;
76 for (auto _ : state) {
77 state.PauseTiming();
78 data = ConstructRandomSet(state.range(0));
79 state.ResumeTiming();
80 for (int j = 0; j < state.range(1); ++j)
81 data.insert(RandomNumber());
82 }
83}
84BENCHMARK(BM_SetInsert)
85 ->Args({1<<10, 128})
86 ->Args({2<<10, 128})
87 ->Args({4<<10, 128})
88 ->Args({8<<10, 128})
89 ->Args({1<<10, 512})
90 ->Args({2<<10, 512})
91 ->Args({4<<10, 512})
92 ->Args({8<<10, 512});
93
94// The preceding code is quite repetitive, and can be replaced with
95// the following short-hand. The following macro will pick a few
96// appropriate arguments in the product of the two specified ranges
97// and will generate a microbenchmark for each such pair.
98BENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {128, 512}});
99
100// For more complex patterns of inputs, passing a custom function
101// to Apply allows programmatic specification of an
102// arbitrary set of arguments to run the microbenchmark on.
103// The following example enumerates a dense range on
104// one parameter, and a sparse range on the second.
105static void CustomArguments(benchmark::internal::Benchmark* b) {
106 for (int i = 0; i <= 10; ++i)
107 for (int j = 32; j <= 1024*1024; j *= 8)
108 b->Args({i, j});
109}
110BENCHMARK(BM_SetInsert)->Apply(CustomArguments);
111
112// Templated microbenchmarks work the same way:
113// Produce then consume 'size' messages 'iters' times
114// Measures throughput in the absence of multiprogramming.
115template <class Q> int BM_Sequential(benchmark::State& state) {
116 Q q;
117 typename Q::value_type v;
118 for (auto _ : state) {
119 for (int i = state.range(0); i--; )
120 q.push(v);
121 for (int e = state.range(0); e--; )
122 q.Wait(&v);
123 }
124 // actually messages, not bytes:
125 state.SetBytesProcessed(state.iterations() * state.range(0));
126}
127BENCHMARK_TEMPLATE(BM_Sequential, WaitQueue<int>)->Range(1<<0, 1<<10);
128
129Use `Benchmark::MinTime(double t)` to set the minimum time used to run the
130benchmark. This option overrides the `benchmark_min_time` flag.
131
132void BM_test(benchmark::State& state) {
133 ... body ...
134}
135BENCHMARK(BM_test)->MinTime(2.0); // Run for at least 2 seconds.
136
137In a multithreaded test, it is guaranteed that none of the threads will start
138until all have reached the loop start, and all will have finished before any
139thread exits the loop body. As such, any global setup or teardown you want to
140do can be wrapped in a check against the thread index:
141
142static void BM_MultiThreaded(benchmark::State& state) {
143 if (state.thread_index() == 0) {
144 // Setup code here.
145 }
146 for (auto _ : state) {
147 // Run the test as normal.
148 }
149 if (state.thread_index() == 0) {
150 // Teardown code here.
151 }
152}
153BENCHMARK(BM_MultiThreaded)->Threads(4);
154
155
156If a benchmark runs a few milliseconds it may be hard to visually compare the
157measured times, since the output data is given in nanoseconds per default. In
158order to manually set the time unit, you can specify it manually:
159
160BENCHMARK(BM_test)->Unit(benchmark::kMillisecond);
161*/
162
163#ifndef BENCHMARK_BENCHMARK_H_
164#define BENCHMARK_BENCHMARK_H_
165
166// The _MSVC_LANG check should detect Visual Studio 2015 Update 3 and newer.
167#if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
168#define BENCHMARK_HAS_CXX11
169#endif
170
171// This _MSC_VER check should detect VS 2017 v15.3 and newer.
172#if __cplusplus >= 201703L || \
173 (defined(_MSC_VER) && _MSC_VER >= 1911 && _MSVC_LANG >= 201703L)
174#define BENCHMARK_HAS_CXX17
175#endif
176
177#include <stdint.h>
178
179#include <algorithm>
180#include <cassert>
181#include <cstddef>
182#include <iosfwd>
183#include <limits>
184#include <map>
185#include <set>
186#include <string>
187#include <utility>
188#include <vector>
189
190#include "benchmark/export.h"
191
192#if defined(BENCHMARK_HAS_CXX11)
193#include <atomic>
194#include <initializer_list>
195#include <type_traits>
196#include <utility>
197#endif
198
199#if defined(_MSC_VER)
200#include <intrin.h> // for _ReadWriteBarrier
201#endif
202
203#ifndef BENCHMARK_HAS_CXX11
204#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \
205 TypeName(const TypeName&); \
206 TypeName& operator=(const TypeName&)
207#else
208#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \
209 TypeName(const TypeName&) = delete; \
210 TypeName& operator=(const TypeName&) = delete
211#endif
212
213#ifdef BENCHMARK_HAS_CXX17
214#define BENCHMARK_UNUSED [[maybe_unused]]
215#elif defined(__GNUC__) || defined(__clang__)
216#define BENCHMARK_UNUSED __attribute__((unused))
217#else
218#define BENCHMARK_UNUSED
219#endif
220
221#if defined(__GNUC__) || defined(__clang__)
222#define BENCHMARK_ALWAYS_INLINE __attribute__((always_inline))
223#define BENCHMARK_NOEXCEPT noexcept
224#define BENCHMARK_NOEXCEPT_OP(x) noexcept(x)
225#elif defined(_MSC_VER) && !defined(__clang__)
226#define BENCHMARK_ALWAYS_INLINE __forceinline
227#if _MSC_VER >= 1900
228#define BENCHMARK_NOEXCEPT noexcept
229#define BENCHMARK_NOEXCEPT_OP(x) noexcept(x)
230#else
231#define BENCHMARK_NOEXCEPT
232#define BENCHMARK_NOEXCEPT_OP(x)
233#endif
234#define __func__ __FUNCTION__
235#else
236#define BENCHMARK_ALWAYS_INLINE
237#define BENCHMARK_NOEXCEPT
238#define BENCHMARK_NOEXCEPT_OP(x)
239#endif
240
241#define BENCHMARK_INTERNAL_TOSTRING2(x) #x
242#define BENCHMARK_INTERNAL_TOSTRING(x) BENCHMARK_INTERNAL_TOSTRING2(x)
243
244// clang-format off
245#if defined(__GNUC__) || defined(__clang__)
246#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)
247#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
248#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
249 _Pragma("GCC diagnostic push") \
250 _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
251#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma("GCC diagnostic pop")
252#else
253#define BENCHMARK_BUILTIN_EXPECT(x, y) x
254#define BENCHMARK_DEPRECATED_MSG(msg)
255#define BENCHMARK_WARNING_MSG(msg) \
256 __pragma(message(__FILE__ "(" BENCHMARK_INTERNAL_TOSTRING( \
257 __LINE__) ") : warning note: " msg))
258#define BENCHMARK_DISABLE_DEPRECATED_WARNING
259#define BENCHMARK_RESTORE_DEPRECATED_WARNING
260#endif
261// clang-format on
262
263#if defined(__GNUC__) && !defined(__clang__)
264#define BENCHMARK_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
265#endif
266
267#ifndef __has_builtin
268#define __has_builtin(x) 0
269#endif
270
271#if defined(__GNUC__) || __has_builtin(__builtin_unreachable)
272#define BENCHMARK_UNREACHABLE() __builtin_unreachable()
273#elif defined(_MSC_VER)
274#define BENCHMARK_UNREACHABLE() __assume(false)
275#else
276#define BENCHMARK_UNREACHABLE() ((void)0)
277#endif
278
279#ifdef BENCHMARK_HAS_CXX11
280#define BENCHMARK_OVERRIDE override
281#else
282#define BENCHMARK_OVERRIDE
283#endif
284
285#if defined(_MSC_VER)
286#pragma warning(push)
287// C4251: <symbol> needs to have dll-interface to be used by clients of class
288#pragma warning(disable : 4251)
289#endif
290
291namespace benchmark {
292class BenchmarkReporter;
293
294BENCHMARK_EXPORT void PrintDefaultHelp();
295
296BENCHMARK_EXPORT void Initialize(int* argc, char** argv,
297 void (*HelperPrinterf)() = PrintDefaultHelp);
298BENCHMARK_EXPORT void Shutdown();
299
300// Report to stdout all arguments in 'argv' as unrecognized except the first.
301// Returns true there is at least on unrecognized argument (i.e. 'argc' > 1).
302BENCHMARK_EXPORT bool ReportUnrecognizedArguments(int argc, char** argv);
303
304// Returns the current value of --benchmark_filter.
305BENCHMARK_EXPORT std::string GetBenchmarkFilter();
306
307// Sets a new value to --benchmark_filter. (This will override this flag's
308// current value).
309// Should be called after `benchmark::Initialize()`, as
310// `benchmark::Initialize()` will override the flag's value.
311BENCHMARK_EXPORT void SetBenchmarkFilter(std::string value);
312
313// Returns the current value of --v (command line value for verbosity).
314BENCHMARK_EXPORT int32_t GetBenchmarkVerbosity();
315
316// Creates a default display reporter. Used by the library when no display
317// reporter is provided, but also made available for external use in case a
318// custom reporter should respect the `--benchmark_format` flag as a fallback
319BENCHMARK_EXPORT BenchmarkReporter* CreateDefaultDisplayReporter();
320
321// Generate a list of benchmarks matching the specified --benchmark_filter flag
322// and if --benchmark_list_tests is specified return after printing the name
323// of each matching benchmark. Otherwise run each matching benchmark and
324// report the results.
325//
326// spec : Specify the benchmarks to run. If users do not specify this arg,
327// then the value of FLAGS_benchmark_filter
328// will be used.
329//
330// The second and third overload use the specified 'display_reporter' and
331// 'file_reporter' respectively. 'file_reporter' will write to the file
332// specified
333// by '--benchmark_output'. If '--benchmark_output' is not given the
334// 'file_reporter' is ignored.
335//
336// RETURNS: The number of matching benchmarks.
337BENCHMARK_EXPORT size_t RunSpecifiedBenchmarks();
338BENCHMARK_EXPORT size_t RunSpecifiedBenchmarks(std::string spec);
339
340BENCHMARK_EXPORT size_t
341RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter);
342BENCHMARK_EXPORT size_t
343RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, std::string spec);
344
345BENCHMARK_EXPORT size_t RunSpecifiedBenchmarks(
346 BenchmarkReporter* display_reporter, BenchmarkReporter* file_reporter);
347BENCHMARK_EXPORT size_t
348RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
349 BenchmarkReporter* file_reporter, std::string spec);
350
351// TimeUnit is passed to a benchmark in order to specify the order of magnitude
352// for the measured time.
353enum TimeUnit { kNanosecond, kMicrosecond, kMillisecond, kSecond };
354
355BENCHMARK_EXPORT TimeUnit GetDefaultTimeUnit();
356
357// Sets the default time unit the benchmarks use
358// Has to be called before the benchmark loop to take effect
359BENCHMARK_EXPORT void SetDefaultTimeUnit(TimeUnit unit);
360
361// If a MemoryManager is registered (via RegisterMemoryManager()),
362// it can be used to collect and report allocation metrics for a run of the
363// benchmark.
365 public:
366 static const int64_t TombstoneValue;
367
368 struct Result {
369 Result()
370 : num_allocs(0),
371 max_bytes_used(0),
372 total_allocated_bytes(TombstoneValue),
373 net_heap_growth(TombstoneValue) {}
374
375 // The number of allocations made in total between Start and Stop.
376 int64_t num_allocs;
377
378 // The peak memory use between Start and Stop.
379 int64_t max_bytes_used;
380
381 // The total memory allocated, in bytes, between Start and Stop.
382 // Init'ed to TombstoneValue if metric not available.
383 int64_t total_allocated_bytes;
384
385 // The net changes in memory, in bytes, between Start and Stop.
386 // ie., total_allocated_bytes - total_deallocated_bytes.
387 // Init'ed to TombstoneValue if metric not available.
388 int64_t net_heap_growth;
389 };
390
391 virtual ~MemoryManager() {}
392
393 // Implement this to start recording allocation information.
394 virtual void Start() = 0;
395
396 // Implement this to stop recording and fill out the given Result structure.
397 BENCHMARK_DEPRECATED_MSG("Use Stop(Result&) instead")
398 virtual void Stop(Result* result) = 0;
399
400 // FIXME(vyng): Make this pure virtual once we've migrated current users.
401 BENCHMARK_DISABLE_DEPRECATED_WARNING
402 virtual void Stop(Result& result) { Stop(&result); }
403 BENCHMARK_RESTORE_DEPRECATED_WARNING
404};
405
406// Register a MemoryManager instance that will be used to collect and report
407// allocation measurements for benchmark runs.
408BENCHMARK_EXPORT
409void RegisterMemoryManager(MemoryManager* memory_manager);
410
411// Add a key-value pair to output as part of the context stanza in the report.
412BENCHMARK_EXPORT
413void AddCustomContext(const std::string& key, const std::string& value);
414
415namespace internal {
416class Benchmark;
417class BenchmarkImp;
418class BenchmarkFamilies;
419
420BENCHMARK_EXPORT
421void UseCharPointer(char const volatile*);
422
423// Take ownership of the pointer and register the benchmark. Return the
424// registered benchmark.
425BENCHMARK_EXPORT Benchmark* RegisterBenchmarkInternal(Benchmark*);
426
427// Ensure that the standard streams are properly initialized in every TU.
428BENCHMARK_EXPORT int InitializeStreams();
429BENCHMARK_UNUSED static int stream_init_anchor = InitializeStreams();
430
431} // namespace internal
432
433#if (!defined(__GNUC__) && !defined(__clang__)) || defined(__pnacl__) || \
434 defined(__EMSCRIPTEN__)
435#define BENCHMARK_HAS_NO_INLINE_ASSEMBLY
436#endif
437
438// Force the compiler to flush pending writes to global memory. Acts as an
439// effective read/write barrier
440#ifdef BENCHMARK_HAS_CXX11
441inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {
442 std::atomic_signal_fence(std::memory_order_acq_rel);
443}
444#endif
445
446// The DoNotOptimize(...) function can be used to prevent a value or
447// expression from being optimized away by the compiler. This function is
448// intended to add little to no overhead.
449// See: https://youtu.be/nXaxk27zwlk?t=2441
450#ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY
451#if !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER)
452template <class Tp>
453inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
454 asm volatile("" : : "r,m"(value) : "memory");
455}
456
457template <class Tp>
458inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {
459#if defined(__clang__)
460 asm volatile("" : "+r,m"(value) : : "memory");
461#else
462 asm volatile("" : "+m,r"(value) : : "memory");
463#endif
464}
465#elif defined(BENCHMARK_HAS_CXX11) && (__GNUC__ >= 5)
466// Workaround for a bug with full argument copy overhead with GCC.
467// See: #1340 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105519
468template <class Tp>
469inline BENCHMARK_ALWAYS_INLINE
470 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
471 (sizeof(Tp) <= sizeof(Tp*))>::type
472 DoNotOptimize(Tp const& value) {
473 asm volatile("" : : "r,m"(value) : "memory");
474}
475
476template <class Tp>
477inline BENCHMARK_ALWAYS_INLINE
478 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
479 (sizeof(Tp) > sizeof(Tp*))>::type
480 DoNotOptimize(Tp const& value) {
481 asm volatile("" : : "m"(value) : "memory");
482}
483
484template <class Tp>
485inline BENCHMARK_ALWAYS_INLINE
486 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
487 (sizeof(Tp) <= sizeof(Tp*))>::type
488 DoNotOptimize(Tp& value) {
489 asm volatile("" : "+m,r"(value) : : "memory");
490}
491
492template <class Tp>
493inline BENCHMARK_ALWAYS_INLINE
494 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
495 (sizeof(Tp) > sizeof(Tp*))>::type
496 DoNotOptimize(Tp& value) {
497 asm volatile("" : "+m"(value) : : "memory");
498}
499
500#else
501// Fallback for GCC < 5. Can add some overhead because the compiler is forced
502// to use memory operations instead of operations with registers.
503// TODO: Remove if GCC < 5 will be unsupported.
504template <class Tp>
505inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
506 asm volatile("" : : "m"(value) : "memory");
507}
508
509template <class Tp>
510inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {
511 asm volatile("" : "+m"(value) : : "memory");
512}
513#endif
514
515#ifndef BENCHMARK_HAS_CXX11
516inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {
517 asm volatile("" : : : "memory");
518}
519#endif
520#elif defined(_MSC_VER)
521template <class Tp>
522inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
523 internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
524 _ReadWriteBarrier();
525}
526
527#ifndef BENCHMARK_HAS_CXX11
528inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() { _ReadWriteBarrier(); }
529#endif
530#else
531template <class Tp>
532inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
533 internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
534}
535// FIXME Add ClobberMemory() for non-gnu and non-msvc compilers, before C++11.
536#endif
537
538// This class is used for user-defined counters.
539class Counter {
540 public:
541 enum Flags {
542 kDefaults = 0,
543 // Mark the counter as a rate. It will be presented divided
544 // by the duration of the benchmark.
545 kIsRate = 1 << 0,
546 // Mark the counter as a thread-average quantity. It will be
547 // presented divided by the number of threads.
548 kAvgThreads = 1 << 1,
549 // Mark the counter as a thread-average rate. See above.
550 kAvgThreadsRate = kIsRate | kAvgThreads,
551 // Mark the counter as a constant value, valid/same for *every* iteration.
552 // When reporting, it will be *multiplied* by the iteration count.
553 kIsIterationInvariant = 1 << 2,
554 // Mark the counter as a constant rate.
555 // When reporting, it will be *multiplied* by the iteration count
556 // and then divided by the duration of the benchmark.
557 kIsIterationInvariantRate = kIsRate | kIsIterationInvariant,
558 // Mark the counter as a iteration-average quantity.
559 // It will be presented divided by the number of iterations.
560 kAvgIterations = 1 << 3,
561 // Mark the counter as a iteration-average rate. See above.
562 kAvgIterationsRate = kIsRate | kAvgIterations,
563
564 // In the end, invert the result. This is always done last!
565 kInvert = 1 << 31
566 };
567
568 enum OneK {
569 // 1'000 items per 1k
570 kIs1000 = 1000,
571 // 1'024 items per 1k
572 kIs1024 = 1024
573 };
574
575 double value;
576 Flags flags;
577 OneK oneK;
578
579 BENCHMARK_ALWAYS_INLINE
580 Counter(double v = 0., Flags f = kDefaults, OneK k = kIs1000)
581 : value(v), flags(f), oneK(k) {}
582
583 BENCHMARK_ALWAYS_INLINE operator double const &() const { return value; }
584 BENCHMARK_ALWAYS_INLINE operator double&() { return value; }
585};
586
587// A helper for user code to create unforeseen combinations of Flags, without
588// having to do this cast manually each time, or providing this operator.
589Counter::Flags inline operator|(const Counter::Flags& LHS,
590 const Counter::Flags& RHS) {
591 return static_cast<Counter::Flags>(static_cast<int>(LHS) |
592 static_cast<int>(RHS));
593}
594
595// This is the container for the user-defined counters.
596typedef std::map<std::string, Counter> UserCounters;
597
598// BigO is passed to a benchmark in order to specify the asymptotic
599// computational
600// complexity for the benchmark. In case oAuto is selected, complexity will be
601// calculated automatically to the best fit.
602enum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLambda };
603
604typedef int64_t IterationCount;
605
606enum StatisticUnit { kTime, kPercentage };
607
608// BigOFunc is passed to a benchmark in order to specify the asymptotic
609// computational complexity for the benchmark.
610typedef double(BigOFunc)(IterationCount);
611
612// StatisticsFunc is passed to a benchmark in order to compute some descriptive
613// statistics over all the measurements of some type
614typedef double(StatisticsFunc)(const std::vector<double>&);
615
616namespace internal {
618 std::string name_;
619 StatisticsFunc* compute_;
620 StatisticUnit unit_;
621
622 Statistics(const std::string& name, StatisticsFunc* compute,
623 StatisticUnit unit = kTime)
624 : name_(name), compute_(compute), unit_(unit) {}
625};
626
628class ThreadTimer;
629class ThreadManager;
631
632enum AggregationReportMode
633#if defined(BENCHMARK_HAS_CXX11)
634 : unsigned
635#else
636#endif
637{
638 // The mode has not been manually specified
639 ARM_Unspecified = 0,
640 // The mode is user-specified.
641 // This may or may not be set when the following bit-flags are set.
642 ARM_Default = 1U << 0U,
643 // File reporter should only output aggregates.
644 ARM_FileReportAggregatesOnly = 1U << 1U,
645 // Display reporter should only output aggregates
646 ARM_DisplayReportAggregatesOnly = 1U << 2U,
647 // Both reporters should only display aggregates.
648 ARM_ReportAggregatesOnly =
649 ARM_FileReportAggregatesOnly | ARM_DisplayReportAggregatesOnly
650};
651
652} // namespace internal
653
654// State is passed to a running Benchmark and contains state for the
655// benchmark to use.
656class BENCHMARK_EXPORT State {
657 public:
658 struct StateIterator;
659 friend struct StateIterator;
660
661 // Returns iterators used to run each iteration of a benchmark using a
662 // C++11 ranged-based for loop. These functions should not be called directly.
663 //
664 // REQUIRES: The benchmark has not started running yet. Neither begin nor end
665 // have been called previously.
666 //
667 // NOTE: KeepRunning may not be used after calling either of these functions.
668 BENCHMARK_ALWAYS_INLINE StateIterator begin();
669 BENCHMARK_ALWAYS_INLINE StateIterator end();
670
671 // Returns true if the benchmark should continue through another iteration.
672 // NOTE: A benchmark may not return from the test until KeepRunning() has
673 // returned false.
674 bool KeepRunning();
675
676 // Returns true iff the benchmark should run n more iterations.
677 // REQUIRES: 'n' > 0.
678 // NOTE: A benchmark must not return from the test until KeepRunningBatch()
679 // has returned false.
680 // NOTE: KeepRunningBatch() may overshoot by up to 'n' iterations.
681 //
682 // Intended usage:
683 // while (state.KeepRunningBatch(1000)) {
684 // // process 1000 elements
685 // }
686 bool KeepRunningBatch(IterationCount n);
687
688 // REQUIRES: timer is running and 'SkipWithError(...)' has not been called
689 // by the current thread.
690 // Stop the benchmark timer. If not called, the timer will be
691 // automatically stopped after the last iteration of the benchmark loop.
692 //
693 // For threaded benchmarks the PauseTiming() function only pauses the timing
694 // for the current thread.
695 //
696 // NOTE: The "real time" measurement is per-thread. If different threads
697 // report different measurements the largest one is reported.
698 //
699 // NOTE: PauseTiming()/ResumeTiming() are relatively
700 // heavyweight, and so their use should generally be avoided
701 // within each benchmark iteration, if possible.
702 void PauseTiming();
703
704 // REQUIRES: timer is not running and 'SkipWithError(...)' has not been called
705 // by the current thread.
706 // Start the benchmark timer. The timer is NOT running on entrance to the
707 // benchmark function. It begins running after control flow enters the
708 // benchmark loop.
709 //
710 // NOTE: PauseTiming()/ResumeTiming() are relatively
711 // heavyweight, and so their use should generally be avoided
712 // within each benchmark iteration, if possible.
713 void ResumeTiming();
714
715 // REQUIRES: 'SkipWithError(...)' has not been called previously by the
716 // current thread.
717 // Report the benchmark as resulting in an error with the specified 'msg'.
718 // After this call the user may explicitly 'return' from the benchmark.
719 //
720 // If the ranged-for style of benchmark loop is used, the user must explicitly
721 // break from the loop, otherwise all future iterations will be run.
722 // If the 'KeepRunning()' loop is used the current thread will automatically
723 // exit the loop at the end of the current iteration.
724 //
725 // For threaded benchmarks only the current thread stops executing and future
726 // calls to `KeepRunning()` will block until all threads have completed
727 // the `KeepRunning()` loop. If multiple threads report an error only the
728 // first error message is used.
729 //
730 // NOTE: Calling 'SkipWithError(...)' does not cause the benchmark to exit
731 // the current scope immediately. If the function is called from within
732 // the 'KeepRunning()' loop the current iteration will finish. It is the users
733 // responsibility to exit the scope as needed.
734 void SkipWithError(const char* msg);
735
736 // Returns true if an error has been reported with 'SkipWithError(...)'.
737 bool error_occurred() const { return error_occurred_; }
738
739 // REQUIRES: called exactly once per iteration of the benchmarking loop.
740 // Set the manually measured time for this benchmark iteration, which
741 // is used instead of automatically measured time if UseManualTime() was
742 // specified.
743 //
744 // For threaded benchmarks the final value will be set to the largest
745 // reported values.
746 void SetIterationTime(double seconds);
747
748 // Set the number of bytes processed by the current benchmark
749 // execution. This routine is typically called once at the end of a
750 // throughput oriented benchmark.
751 //
752 // REQUIRES: a benchmark has exited its benchmarking loop.
753 BENCHMARK_ALWAYS_INLINE
754 void SetBytesProcessed(int64_t bytes) {
755 counters["bytes_per_second"] =
756 Counter(static_cast<double>(bytes), Counter::kIsRate, Counter::kIs1024);
757 }
758
759 BENCHMARK_ALWAYS_INLINE
760 int64_t bytes_processed() const {
761 if (counters.find("bytes_per_second") != counters.end())
762 return static_cast<int64_t>(counters.at("bytes_per_second"));
763 return 0;
764 }
765
766 // If this routine is called with complexity_n > 0 and complexity report is
767 // requested for the
768 // family benchmark, then current benchmark will be part of the computation
769 // and complexity_n will
770 // represent the length of N.
771 BENCHMARK_ALWAYS_INLINE
772 void SetComplexityN(int64_t complexity_n) { complexity_n_ = complexity_n; }
773
774 BENCHMARK_ALWAYS_INLINE
775 int64_t complexity_length_n() const { return complexity_n_; }
776
777 // If this routine is called with items > 0, then an items/s
778 // label is printed on the benchmark report line for the currently
779 // executing benchmark. It is typically called at the end of a processing
780 // benchmark where a processing items/second output is desired.
781 //
782 // REQUIRES: a benchmark has exited its benchmarking loop.
783 BENCHMARK_ALWAYS_INLINE
784 void SetItemsProcessed(int64_t items) {
785 counters["items_per_second"] =
786 Counter(static_cast<double>(items), benchmark::Counter::kIsRate);
787 }
788
789 BENCHMARK_ALWAYS_INLINE
790 int64_t items_processed() const {
791 if (counters.find("items_per_second") != counters.end())
792 return static_cast<int64_t>(counters.at("items_per_second"));
793 return 0;
794 }
795
796 // If this routine is called, the specified label is printed at the
797 // end of the benchmark report line for the currently executing
798 // benchmark. Example:
799 // static void BM_Compress(benchmark::State& state) {
800 // ...
801 // double compress = input_size / output_size;
802 // state.SetLabel(StrFormat("compress:%.1f%%", 100.0*compression));
803 // }
804 // Produces output that looks like:
805 // BM_Compress 50 50 14115038 compress:27.3%
806 //
807 // REQUIRES: a benchmark has exited its benchmarking loop.
808 void SetLabel(const char* label);
809
810 void BENCHMARK_ALWAYS_INLINE SetLabel(const std::string& str) {
811 this->SetLabel(str.c_str());
812 }
813
814 // Range arguments for this run. CHECKs if the argument has been set.
815 BENCHMARK_ALWAYS_INLINE
816 int64_t range(std::size_t pos = 0) const {
817 assert(range_.size() > pos);
818 return range_[pos];
819 }
820
821 BENCHMARK_DEPRECATED_MSG("use 'range(0)' instead")
822 int64_t range_x() const { return range(0); }
823
824 BENCHMARK_DEPRECATED_MSG("use 'range(1)' instead")
825 int64_t range_y() const { return range(1); }
826
827 // Number of threads concurrently executing the benchmark.
828 BENCHMARK_ALWAYS_INLINE
829 int threads() const { return threads_; }
830
831 // Index of the executing thread. Values from [0, threads).
832 BENCHMARK_ALWAYS_INLINE
833 int thread_index() const { return thread_index_; }
834
835 BENCHMARK_ALWAYS_INLINE
836 IterationCount iterations() const {
837 if (BENCHMARK_BUILTIN_EXPECT(!started_, false)) {
838 return 0;
839 }
840 return max_iterations - total_iterations_ + batch_leftover_;
841 }
842
843 private:
844 // items we expect on the first cache line (ie 64 bytes of the struct)
845 // When total_iterations_ is 0, KeepRunning() and friends will return false.
846 // May be larger than max_iterations.
847 IterationCount total_iterations_;
848
849 // When using KeepRunningBatch(), batch_leftover_ holds the number of
850 // iterations beyond max_iters that were run. Used to track
851 // completed_iterations_ accurately.
852 IterationCount batch_leftover_;
853
854 public:
855 const IterationCount max_iterations;
856
857 private:
858 bool started_;
859 bool finished_;
860 bool error_occurred_;
861
862 // items we don't need on the first cache line
863 std::vector<int64_t> range_;
864
865 int64_t complexity_n_;
866
867 public:
868 // Container for user-defined counters.
869 UserCounters counters;
870
871 private:
872 State(IterationCount max_iters, const std::vector<int64_t>& ranges,
873 int thread_i, int n_threads, internal::ThreadTimer* timer,
875 internal::PerfCountersMeasurement* perf_counters_measurement);
876
877 void StartKeepRunning();
878 // Implementation of KeepRunning() and KeepRunningBatch().
879 // is_batch must be true unless n is 1.
880 bool KeepRunningInternal(IterationCount n, bool is_batch);
881 void FinishKeepRunning();
882
883 const int thread_index_;
884 const int threads_;
885
886 internal::ThreadTimer* const timer_;
887 internal::ThreadManager* const manager_;
888 internal::PerfCountersMeasurement* const perf_counters_measurement_;
889
890 friend class internal::BenchmarkInstance;
891};
892
893inline BENCHMARK_ALWAYS_INLINE bool State::KeepRunning() {
894 return KeepRunningInternal(1, /*is_batch=*/false);
895}
896
897inline BENCHMARK_ALWAYS_INLINE bool State::KeepRunningBatch(IterationCount n) {
898 return KeepRunningInternal(n, /*is_batch=*/true);
899}
900
901inline BENCHMARK_ALWAYS_INLINE bool State::KeepRunningInternal(IterationCount n,
902 bool is_batch) {
903 // total_iterations_ is set to 0 by the constructor, and always set to a
904 // nonzero value by StartKepRunning().
905 assert(n > 0);
906 // n must be 1 unless is_batch is true.
907 assert(is_batch || n == 1);
908 if (BENCHMARK_BUILTIN_EXPECT(total_iterations_ >= n, true)) {
909 total_iterations_ -= n;
910 return true;
911 }
912 if (!started_) {
913 StartKeepRunning();
914 if (!error_occurred_ && total_iterations_ >= n) {
915 total_iterations_ -= n;
916 return true;
917 }
918 }
919 // For non-batch runs, total_iterations_ must be 0 by now.
920 if (is_batch && total_iterations_ != 0) {
921 batch_leftover_ = n - total_iterations_;
922 total_iterations_ = 0;
923 return true;
924 }
925 FinishKeepRunning();
926 return false;
927}
928
930 struct BENCHMARK_UNUSED Value {};
931 typedef std::forward_iterator_tag iterator_category;
932 typedef Value value_type;
933 typedef Value reference;
934 typedef Value pointer;
935 typedef std::ptrdiff_t difference_type;
936
937 private:
938 friend class State;
939 BENCHMARK_ALWAYS_INLINE
940 StateIterator() : cached_(0), parent_() {}
941
942 BENCHMARK_ALWAYS_INLINE
943 explicit StateIterator(State* st)
944 : cached_(st->error_occurred_ ? 0 : st->max_iterations), parent_(st) {}
945
946 public:
947 BENCHMARK_ALWAYS_INLINE
948 Value operator*() const { return Value(); }
949
950 BENCHMARK_ALWAYS_INLINE
951 StateIterator& operator++() {
952 assert(cached_ > 0);
953 --cached_;
954 return *this;
955 }
956
957 BENCHMARK_ALWAYS_INLINE
958 bool operator!=(StateIterator const&) const {
959 if (BENCHMARK_BUILTIN_EXPECT(cached_ != 0, true)) return true;
960 parent_->FinishKeepRunning();
961 return false;
962 }
963
964 private:
965 IterationCount cached_;
966 State* const parent_;
967};
968
969inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::begin() {
970 return StateIterator(this);
971}
972inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::end() {
973 StartKeepRunning();
974 return StateIterator();
975}
976
977namespace internal {
978
979typedef void(Function)(State&);
980
981// ------------------------------------------------------
982// Benchmark registration object. The BENCHMARK() macro expands
983// into an internal::Benchmark* object. Various methods can
984// be called on this object to change the properties of the benchmark.
985// Each method returns "this" so that multiple method calls can
986// chained into one expression.
987class BENCHMARK_EXPORT Benchmark {
988 public:
989 virtual ~Benchmark();
990
991 // Note: the following methods all return "this" so that multiple
992 // method calls can be chained together in one expression.
993
994 // Specify the name of the benchmark
995 Benchmark* Name(const std::string& name);
996
997 // Run this benchmark once with "x" as the extra argument passed
998 // to the function.
999 // REQUIRES: The function passed to the constructor must accept an arg1.
1000 Benchmark* Arg(int64_t x);
1001
1002 // Run this benchmark with the given time unit for the generated output report
1003 Benchmark* Unit(TimeUnit unit);
1004
1005 // Run this benchmark once for a number of values picked from the
1006 // range [start..limit]. (start and limit are always picked.)
1007 // REQUIRES: The function passed to the constructor must accept an arg1.
1008 Benchmark* Range(int64_t start, int64_t limit);
1009
1010 // Run this benchmark once for all values in the range [start..limit] with
1011 // specific step
1012 // REQUIRES: The function passed to the constructor must accept an arg1.
1013 Benchmark* DenseRange(int64_t start, int64_t limit, int step = 1);
1014
1015 // Run this benchmark once with "args" as the extra arguments passed
1016 // to the function.
1017 // REQUIRES: The function passed to the constructor must accept arg1, arg2 ...
1018 Benchmark* Args(const std::vector<int64_t>& args);
1019
1020 // Equivalent to Args({x, y})
1021 // NOTE: This is a legacy C++03 interface provided for compatibility only.
1022 // New code should use 'Args'.
1023 Benchmark* ArgPair(int64_t x, int64_t y) {
1024 std::vector<int64_t> args;
1025 args.push_back(x);
1026 args.push_back(y);
1027 return Args(args);
1028 }
1029
1030 // Run this benchmark once for a number of values picked from the
1031 // ranges [start..limit]. (starts and limits are always picked.)
1032 // REQUIRES: The function passed to the constructor must accept arg1, arg2 ...
1033 Benchmark* Ranges(const std::vector<std::pair<int64_t, int64_t> >& ranges);
1034
1035 // Run this benchmark once for each combination of values in the (cartesian)
1036 // product of the supplied argument lists.
1037 // REQUIRES: The function passed to the constructor must accept arg1, arg2 ...
1038 Benchmark* ArgsProduct(const std::vector<std::vector<int64_t> >& arglists);
1039
1040 // Equivalent to ArgNames({name})
1041 Benchmark* ArgName(const std::string& name);
1042
1043 // Set the argument names to display in the benchmark name. If not called,
1044 // only argument values will be shown.
1045 Benchmark* ArgNames(const std::vector<std::string>& names);
1046
1047 // Equivalent to Ranges({{lo1, hi1}, {lo2, hi2}}).
1048 // NOTE: This is a legacy C++03 interface provided for compatibility only.
1049 // New code should use 'Ranges'.
1050 Benchmark* RangePair(int64_t lo1, int64_t hi1, int64_t lo2, int64_t hi2) {
1051 std::vector<std::pair<int64_t, int64_t> > ranges;
1052 ranges.push_back(std::make_pair(lo1, hi1));
1053 ranges.push_back(std::make_pair(lo2, hi2));
1054 return Ranges(ranges);
1055 }
1056
1057 // Have "setup" and/or "teardown" invoked once for every benchmark run.
1058 // If the benchmark is multi-threaded (will run in k threads concurrently),
1059 // the setup callback will be be invoked exactly once (not k times) before
1060 // each run with k threads. Time allowing (e.g. for a short benchmark), there
1061 // may be multiple such runs per benchmark, each run with its own
1062 // "setup"/"teardown".
1063 //
1064 // If the benchmark uses different size groups of threads (e.g. via
1065 // ThreadRange), the above will be true for each size group.
1066 //
1067 // The callback will be passed a State object, which includes the number
1068 // of threads, thread-index, benchmark arguments, etc.
1069 //
1070 // The callback must not be NULL or self-deleting.
1071 Benchmark* Setup(void (*setup)(const benchmark::State&));
1072 Benchmark* Teardown(void (*teardown)(const benchmark::State&));
1073
1074 // Pass this benchmark object to *func, which can customize
1075 // the benchmark by calling various methods like Arg, Args,
1076 // Threads, etc.
1077 Benchmark* Apply(void (*func)(Benchmark* benchmark));
1078
1079 // Set the range multiplier for non-dense range. If not called, the range
1080 // multiplier kRangeMultiplier will be used.
1081 Benchmark* RangeMultiplier(int multiplier);
1082
1083 // Set the minimum amount of time to use when running this benchmark. This
1084 // option overrides the `benchmark_min_time` flag.
1085 // REQUIRES: `t > 0` and `Iterations` has not been called on this benchmark.
1086 Benchmark* MinTime(double t);
1087
1088 // Set the minimum amount of time to run the benchmark before taking runtimes
1089 // of this benchmark into account. This
1090 // option overrides the `benchmark_min_warmup_time` flag.
1091 // REQUIRES: `t >= 0` and `Iterations` has not been called on this benchmark.
1092 Benchmark* MinWarmUpTime(double t);
1093
1094 // Specify the amount of iterations that should be run by this benchmark.
1095 // REQUIRES: 'n > 0' and `MinTime` has not been called on this benchmark.
1096 //
1097 // NOTE: This function should only be used when *exact* iteration control is
1098 // needed and never to control or limit how long a benchmark runs, where
1099 // `--benchmark_min_time=N` or `MinTime(...)` should be used instead.
1100 Benchmark* Iterations(IterationCount n);
1101
1102 // Specify the amount of times to repeat this benchmark. This option overrides
1103 // the `benchmark_repetitions` flag.
1104 // REQUIRES: `n > 0`
1105 Benchmark* Repetitions(int n);
1106
1107 // Specify if each repetition of the benchmark should be reported separately
1108 // or if only the final statistics should be reported. If the benchmark
1109 // is not repeated then the single result is always reported.
1110 // Applies to *ALL* reporters (display and file).
1111 Benchmark* ReportAggregatesOnly(bool value = true);
1112
1113 // Same as ReportAggregatesOnly(), but applies to display reporter only.
1114 Benchmark* DisplayAggregatesOnly(bool value = true);
1115
1116 // By default, the CPU time is measured only for the main thread, which may
1117 // be unrepresentative if the benchmark uses threads internally. If called,
1118 // the total CPU time spent by all the threads will be measured instead.
1119 // By default, the only the main thread CPU time will be measured.
1120 Benchmark* MeasureProcessCPUTime();
1121
1122 // If a particular benchmark should use the Wall clock instead of the CPU time
1123 // (be it either the CPU time of the main thread only (default), or the
1124 // total CPU usage of the benchmark), call this method. If called, the elapsed
1125 // (wall) time will be used to control how many iterations are run, and in the
1126 // printing of items/second or MB/seconds values.
1127 // If not called, the CPU time used by the benchmark will be used.
1128 Benchmark* UseRealTime();
1129
1130 // If a benchmark must measure time manually (e.g. if GPU execution time is
1131 // being
1132 // measured), call this method. If called, each benchmark iteration should
1133 // call
1134 // SetIterationTime(seconds) to report the measured time, which will be used
1135 // to control how many iterations are run, and in the printing of items/second
1136 // or MB/second values.
1137 Benchmark* UseManualTime();
1138
1139 // Set the asymptotic computational complexity for the benchmark. If called
1140 // the asymptotic computational complexity will be shown on the output.
1141 Benchmark* Complexity(BigO complexity = benchmark::oAuto);
1142
1143 // Set the asymptotic computational complexity for the benchmark. If called
1144 // the asymptotic computational complexity will be shown on the output.
1145 Benchmark* Complexity(BigOFunc* complexity);
1146
1147 // Add this statistics to be computed over all the values of benchmark run
1148 Benchmark* ComputeStatistics(const std::string& name,
1149 StatisticsFunc* statistics,
1150 StatisticUnit unit = kTime);
1151
1152 // Support for running multiple copies of the same benchmark concurrently
1153 // in multiple threads. This may be useful when measuring the scaling
1154 // of some piece of code.
1155
1156 // Run one instance of this benchmark concurrently in t threads.
1157 Benchmark* Threads(int t);
1158
1159 // Pick a set of values T from [min_threads,max_threads].
1160 // min_threads and max_threads are always included in T. Run this
1161 // benchmark once for each value in T. The benchmark run for a
1162 // particular value t consists of t threads running the benchmark
1163 // function concurrently. For example, consider:
1164 // BENCHMARK(Foo)->ThreadRange(1,16);
1165 // This will run the following benchmarks:
1166 // Foo in 1 thread
1167 // Foo in 2 threads
1168 // Foo in 4 threads
1169 // Foo in 8 threads
1170 // Foo in 16 threads
1171 Benchmark* ThreadRange(int min_threads, int max_threads);
1172
1173 // For each value n in the range, run this benchmark once using n threads.
1174 // min_threads and max_threads are always included in the range.
1175 // stride specifies the increment. E.g. DenseThreadRange(1, 8, 3) starts
1176 // a benchmark with 1, 4, 7 and 8 threads.
1177 Benchmark* DenseThreadRange(int min_threads, int max_threads, int stride = 1);
1178
1179 // Equivalent to ThreadRange(NumCPUs(), NumCPUs())
1180 Benchmark* ThreadPerCpu();
1181
1182 virtual void Run(State& state) = 0;
1183
1184 TimeUnit GetTimeUnit() const;
1185
1186 protected:
1187 explicit Benchmark(const char* name);
1188 void SetName(const char* name);
1189
1190 int ArgsCnt() const;
1191
1192 private:
1193 friend class BenchmarkFamilies;
1194 friend class BenchmarkInstance;
1195
1196 std::string name_;
1197 AggregationReportMode aggregation_report_mode_;
1198 std::vector<std::string> arg_names_; // Args for all benchmark runs
1199 std::vector<std::vector<int64_t> > args_; // Args for all benchmark runs
1200
1201 TimeUnit time_unit_;
1202 bool use_default_time_unit_;
1203
1204 int range_multiplier_;
1205 double min_time_;
1206 double min_warmup_time_;
1207 IterationCount iterations_;
1208 int repetitions_;
1209 bool measure_process_cpu_time_;
1210 bool use_real_time_;
1211 bool use_manual_time_;
1212 BigO complexity_;
1213 BigOFunc* complexity_lambda_;
1214 std::vector<Statistics> statistics_;
1215 std::vector<int> thread_counts_;
1216
1217 typedef void (*callback_function)(const benchmark::State&);
1218 callback_function setup_;
1219 callback_function teardown_;
1220
1221 Benchmark(Benchmark const&)
1222#if defined(BENCHMARK_HAS_CXX11)
1223 = delete
1224#endif
1225 ;
1226
1227 Benchmark& operator=(Benchmark const&)
1228#if defined(BENCHMARK_HAS_CXX11)
1229 = delete
1230#endif
1231 ;
1232};
1233
1234} // namespace internal
1235
1236// Create and register a benchmark with the specified 'name' that invokes
1237// the specified functor 'fn'.
1238//
1239// RETURNS: A pointer to the registered benchmark.
1240internal::Benchmark* RegisterBenchmark(const char* name,
1241 internal::Function* fn);
1242
1243#if defined(BENCHMARK_HAS_CXX11)
1244template <class Lambda>
1245internal::Benchmark* RegisterBenchmark(const char* name, Lambda&& fn);
1246#endif
1247
1248// Remove all registered benchmarks. All pointers to previously registered
1249// benchmarks are invalidated.
1250BENCHMARK_EXPORT void ClearRegisteredBenchmarks();
1251
1252namespace internal {
1253// The class used to hold all Benchmarks created from static function.
1254// (ie those created using the BENCHMARK(...) macros.
1255class BENCHMARK_EXPORT FunctionBenchmark : public Benchmark {
1256 public:
1257 FunctionBenchmark(const char* name, Function* func)
1258 : Benchmark(name), func_(func) {}
1259
1260 virtual void Run(State& st) BENCHMARK_OVERRIDE;
1261
1262 private:
1263 Function* func_;
1264};
1265
1266#ifdef BENCHMARK_HAS_CXX11
1267template <class Lambda>
1268class LambdaBenchmark : public Benchmark {
1269 public:
1270 virtual void Run(State& st) BENCHMARK_OVERRIDE { lambda_(st); }
1271
1272 private:
1273 template <class OLambda>
1274 LambdaBenchmark(const char* name, OLambda&& lam)
1275 : Benchmark(name), lambda_(std::forward<OLambda>(lam)) {}
1276
1277 LambdaBenchmark(LambdaBenchmark const&) = delete;
1278
1279 template <class Lam> // NOLINTNEXTLINE(readability-redundant-declaration)
1280 friend Benchmark* ::benchmark::RegisterBenchmark(const char*, Lam&&);
1281
1282 Lambda lambda_;
1283};
1284#endif
1285} // namespace internal
1286
1287inline internal::Benchmark* RegisterBenchmark(const char* name,
1288 internal::Function* fn) {
1289 return internal::RegisterBenchmarkInternal(
1290 ::new internal::FunctionBenchmark(name, fn));
1291}
1292
1293#ifdef BENCHMARK_HAS_CXX11
1294template <class Lambda>
1295internal::Benchmark* RegisterBenchmark(const char* name, Lambda&& fn) {
1296 using BenchType =
1297 internal::LambdaBenchmark<typename std::decay<Lambda>::type>;
1298 return internal::RegisterBenchmarkInternal(
1299 ::new BenchType(name, std::forward<Lambda>(fn)));
1300}
1301#endif
1302
1303#if defined(BENCHMARK_HAS_CXX11) && \
1304 (!defined(BENCHMARK_GCC_VERSION) || BENCHMARK_GCC_VERSION >= 409)
1305template <class Lambda, class... Args>
1306internal::Benchmark* RegisterBenchmark(const char* name, Lambda&& fn,
1307 Args&&... args) {
1308 return benchmark::RegisterBenchmark(
1309 name, [=](benchmark::State& st) { fn(st, args...); });
1310}
1311#else
1312#define BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK
1313#endif
1314
1315// The base class for all fixture tests.
1317 public:
1318 Fixture() : internal::Benchmark("") {}
1319
1320 virtual void Run(State& st) BENCHMARK_OVERRIDE {
1321 this->SetUp(st);
1322 this->BenchmarkCase(st);
1323 this->TearDown(st);
1324 }
1325
1326 // These will be deprecated ...
1327 virtual void SetUp(const State&) {}
1328 virtual void TearDown(const State&) {}
1329 // ... In favor of these.
1330 virtual void SetUp(State& st) { SetUp(const_cast<const State&>(st)); }
1331 virtual void TearDown(State& st) { TearDown(const_cast<const State&>(st)); }
1332
1333 protected:
1334 virtual void BenchmarkCase(State&) = 0;
1335};
1336} // namespace benchmark
1337
1338// ------------------------------------------------------
1339// Macro to register benchmarks
1340
1341// Check that __COUNTER__ is defined and that __COUNTER__ increases by 1
1342// every time it is expanded. X + 1 == X + 0 is used in case X is defined to be
1343// empty. If X is empty the expression becomes (+1 == +0).
1344#if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0)
1345#define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__
1346#else
1347#define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__
1348#endif
1349
1350// Helpers for generating unique variable names
1351#ifdef BENCHMARK_HAS_CXX11
1352#define BENCHMARK_PRIVATE_NAME(...) \
1353 BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, \
1354 __VA_ARGS__)
1355#else
1356#define BENCHMARK_PRIVATE_NAME(n) \
1357 BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, n)
1358#endif // BENCHMARK_HAS_CXX11
1359
1360#define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c)
1361#define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c
1362// Helper for concatenation with macro name expansion
1363#define BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method) \
1364 BaseClass##_##Method##_Benchmark
1365
1366#define BENCHMARK_PRIVATE_DECLARE(n) \
1367 static ::benchmark::internal::Benchmark* BENCHMARK_PRIVATE_NAME(n) \
1368 BENCHMARK_UNUSED
1369
1370#ifdef BENCHMARK_HAS_CXX11
1371#define BENCHMARK(...) \
1372 BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
1373 (::benchmark::internal::RegisterBenchmarkInternal( \
1374 new ::benchmark::internal::FunctionBenchmark(#__VA_ARGS__, \
1375 &__VA_ARGS__)))
1376#else
1377#define BENCHMARK(n) \
1378 BENCHMARK_PRIVATE_DECLARE(n) = \
1379 (::benchmark::internal::RegisterBenchmarkInternal( \
1380 new ::benchmark::internal::FunctionBenchmark(#n, n)))
1381#endif // BENCHMARK_HAS_CXX11
1382
1383// Old-style macros
1384#define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a))
1385#define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->Args({(a1), (a2)})
1386#define BENCHMARK_WITH_UNIT(n, t) BENCHMARK(n)->Unit((t))
1387#define BENCHMARK_RANGE(n, lo, hi) BENCHMARK(n)->Range((lo), (hi))
1388#define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \
1389 BENCHMARK(n)->RangePair({{(l1), (h1)}, {(l2), (h2)}})
1390
1391#ifdef BENCHMARK_HAS_CXX11
1392
1393// Register a benchmark which invokes the function specified by `func`
1394// with the additional arguments specified by `...`.
1395//
1396// For example:
1397//
1398// template <class ...ExtraArgs>`
1399// void BM_takes_args(benchmark::State& state, ExtraArgs&&... extra_args) {
1400// [...]
1401//}
1402// /* Registers a benchmark named "BM_takes_args/int_string_test` */
1403// BENCHMARK_CAPTURE(BM_takes_args, int_string_test, 42, std::string("abc"));
1404#define BENCHMARK_CAPTURE(func, test_case_name, ...) \
1405 BENCHMARK_PRIVATE_DECLARE(func) = \
1406 (::benchmark::internal::RegisterBenchmarkInternal( \
1407 new ::benchmark::internal::FunctionBenchmark( \
1408 #func "/" #test_case_name, \
1409 [](::benchmark::State& st) { func(st, __VA_ARGS__); })))
1410
1411#endif // BENCHMARK_HAS_CXX11
1412
1413// This will register a benchmark for a templatized function. For example:
1414//
1415// template<int arg>
1416// void BM_Foo(int iters);
1417//
1418// BENCHMARK_TEMPLATE(BM_Foo, 1);
1419//
1420// will register BM_Foo<1> as a benchmark.
1421#define BENCHMARK_TEMPLATE1(n, a) \
1422 BENCHMARK_PRIVATE_DECLARE(n) = \
1423 (::benchmark::internal::RegisterBenchmarkInternal( \
1424 new ::benchmark::internal::FunctionBenchmark(#n "<" #a ">", n<a>)))
1425
1426#define BENCHMARK_TEMPLATE2(n, a, b) \
1427 BENCHMARK_PRIVATE_DECLARE(n) = \
1428 (::benchmark::internal::RegisterBenchmarkInternal( \
1429 new ::benchmark::internal::FunctionBenchmark(#n "<" #a "," #b ">", \
1430 n<a, b>)))
1431
1432#ifdef BENCHMARK_HAS_CXX11
1433#define BENCHMARK_TEMPLATE(n, ...) \
1434 BENCHMARK_PRIVATE_DECLARE(n) = \
1435 (::benchmark::internal::RegisterBenchmarkInternal( \
1436 new ::benchmark::internal::FunctionBenchmark( \
1437 #n "<" #__VA_ARGS__ ">", n<__VA_ARGS__>)))
1438#else
1439#define BENCHMARK_TEMPLATE(n, a) BENCHMARK_TEMPLATE1(n, a)
1440#endif
1441
1442#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1443 class BaseClass##_##Method##_Benchmark : public BaseClass { \
1444 public: \
1445 BaseClass##_##Method##_Benchmark() { \
1446 this->SetName(#BaseClass "/" #Method); \
1447 } \
1448 \
1449 protected: \
1450 virtual void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \
1451 };
1452
1453#define BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1454 class BaseClass##_##Method##_Benchmark : public BaseClass<a> { \
1455 public: \
1456 BaseClass##_##Method##_Benchmark() { \
1457 this->SetName(#BaseClass "<" #a ">/" #Method); \
1458 } \
1459 \
1460 protected: \
1461 virtual void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \
1462 };
1463
1464#define BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1465 class BaseClass##_##Method##_Benchmark : public BaseClass<a, b> { \
1466 public: \
1467 BaseClass##_##Method##_Benchmark() { \
1468 this->SetName(#BaseClass "<" #a "," #b ">/" #Method); \
1469 } \
1470 \
1471 protected: \
1472 virtual void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \
1473 };
1474
1475#ifdef BENCHMARK_HAS_CXX11
1476#define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, ...) \
1477 class BaseClass##_##Method##_Benchmark : public BaseClass<__VA_ARGS__> { \
1478 public: \
1479 BaseClass##_##Method##_Benchmark() { \
1480 this->SetName(#BaseClass "<" #__VA_ARGS__ ">/" #Method); \
1481 } \
1482 \
1483 protected: \
1484 virtual void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \
1485 };
1486#else
1487#define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(n, a) \
1488 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(n, a)
1489#endif
1490
1491#define BENCHMARK_DEFINE_F(BaseClass, Method) \
1492 BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1493 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1494
1495#define BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a) \
1496 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1497 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1498
1499#define BENCHMARK_TEMPLATE2_DEFINE_F(BaseClass, Method, a, b) \
1500 BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1501 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1502
1503#ifdef BENCHMARK_HAS_CXX11
1504#define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, ...) \
1505 BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \
1506 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1507#else
1508#define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, a) \
1509 BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a)
1510#endif
1511
1512#define BENCHMARK_REGISTER_F(BaseClass, Method) \
1513 BENCHMARK_PRIVATE_REGISTER_F(BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method))
1514
1515#define BENCHMARK_PRIVATE_REGISTER_F(TestName) \
1516 BENCHMARK_PRIVATE_DECLARE(TestName) = \
1517 (::benchmark::internal::RegisterBenchmarkInternal(new TestName()))
1518
1519// This macro will define and register a benchmark within a fixture class.
1520#define BENCHMARK_F(BaseClass, Method) \
1521 BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1522 BENCHMARK_REGISTER_F(BaseClass, Method); \
1523 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1524
1525#define BENCHMARK_TEMPLATE1_F(BaseClass, Method, a) \
1526 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1527 BENCHMARK_REGISTER_F(BaseClass, Method); \
1528 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1529
1530#define BENCHMARK_TEMPLATE2_F(BaseClass, Method, a, b) \
1531 BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1532 BENCHMARK_REGISTER_F(BaseClass, Method); \
1533 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1534
1535#ifdef BENCHMARK_HAS_CXX11
1536#define BENCHMARK_TEMPLATE_F(BaseClass, Method, ...) \
1537 BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \
1538 BENCHMARK_REGISTER_F(BaseClass, Method); \
1539 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1540#else
1541#define BENCHMARK_TEMPLATE_F(BaseClass, Method, a) \
1542 BENCHMARK_TEMPLATE1_F(BaseClass, Method, a)
1543#endif
1544
1545// Helper macro to create a main routine in a test that runs the benchmarks
1546#define BENCHMARK_MAIN() \
1547 int main(int argc, char** argv) { \
1548 ::benchmark::Initialize(&argc, argv); \
1549 if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; \
1550 ::benchmark::RunSpecifiedBenchmarks(); \
1551 ::benchmark::Shutdown(); \
1552 return 0; \
1553 } \
1554 int main(int, char**)
1555
1556// ------------------------------------------------------
1557// Benchmark Reporters
1558
1559namespace benchmark {
1560
1561struct BENCHMARK_EXPORT CPUInfo {
1562 struct CacheInfo {
1563 std::string type;
1564 int level;
1565 int size;
1566 int num_sharing;
1567 };
1568
1569 enum Scaling { UNKNOWN, ENABLED, DISABLED };
1570
1571 int num_cpus;
1572 Scaling scaling;
1573 double cycles_per_second;
1574 std::vector<CacheInfo> caches;
1575 std::vector<double> load_avg;
1576
1577 static const CPUInfo& Get();
1578
1579 private:
1580 CPUInfo();
1581 BENCHMARK_DISALLOW_COPY_AND_ASSIGN(CPUInfo);
1582};
1583
1584// Adding Struct for System Information
1585struct BENCHMARK_EXPORT SystemInfo {
1586 std::string name;
1587 static const SystemInfo& Get();
1588
1589 private:
1590 SystemInfo();
1591 BENCHMARK_DISALLOW_COPY_AND_ASSIGN(SystemInfo);
1592};
1593
1594// BenchmarkName contains the components of the Benchmark's name
1595// which allows individual fields to be modified or cleared before
1596// building the final name using 'str()'.
1597struct BENCHMARK_EXPORT BenchmarkName {
1598 std::string function_name;
1599 std::string args;
1600 std::string min_time;
1601 std::string min_warmup_time;
1602 std::string iterations;
1603 std::string repetitions;
1604 std::string time_type;
1605 std::string threads;
1606
1607 // Return the full name of the benchmark with each non-empty
1608 // field separated by a '/'
1609 std::string str() const;
1610};
1611
1612// Interface for custom benchmark result printers.
1613// By default, benchmark reports are printed to stdout. However an application
1614// can control the destination of the reports by calling
1615// RunSpecifiedBenchmarks and passing it a custom reporter object.
1616// The reporter object must implement the following interface.
1617class BENCHMARK_EXPORT BenchmarkReporter {
1618 public:
1619 struct Context {
1620 CPUInfo const& cpu_info;
1621 SystemInfo const& sys_info;
1622 // The number of chars in the longest benchmark name.
1623 size_t name_field_width;
1624 static const char* executable_name;
1625 Context();
1626 };
1627
1628 struct BENCHMARK_EXPORT Run {
1629 static const int64_t no_repetition_index = -1;
1630 enum RunType { RT_Iteration, RT_Aggregate };
1631
1632 Run()
1633 : run_type(RT_Iteration),
1634 aggregate_unit(kTime),
1635 error_occurred(false),
1636 iterations(1),
1637 threads(1),
1638 time_unit(GetDefaultTimeUnit()),
1639 real_accumulated_time(0),
1640 cpu_accumulated_time(0),
1641 max_heapbytes_used(0),
1642 complexity(oNone),
1643 complexity_lambda(),
1644 complexity_n(0),
1645 report_big_o(false),
1646 report_rms(false),
1647 memory_result(NULL),
1648 allocs_per_iter(0.0) {}
1649
1650 std::string benchmark_name() const;
1651 BenchmarkName run_name;
1652 int64_t family_index;
1653 int64_t per_family_instance_index;
1654 RunType run_type;
1655 std::string aggregate_name;
1656 StatisticUnit aggregate_unit;
1657 std::string report_label; // Empty if not set by benchmark.
1658 bool error_occurred;
1659 std::string error_message;
1660
1661 IterationCount iterations;
1662 int64_t threads;
1663 int64_t repetition_index;
1664 int64_t repetitions;
1665 TimeUnit time_unit;
1666 double real_accumulated_time;
1667 double cpu_accumulated_time;
1668
1669 // Return a value representing the real time per iteration in the unit
1670 // specified by 'time_unit'.
1671 // NOTE: If 'iterations' is zero the returned value represents the
1672 // accumulated time.
1673 double GetAdjustedRealTime() const;
1674
1675 // Return a value representing the cpu time per iteration in the unit
1676 // specified by 'time_unit'.
1677 // NOTE: If 'iterations' is zero the returned value represents the
1678 // accumulated time.
1679 double GetAdjustedCPUTime() const;
1680
1681 // This is set to 0.0 if memory tracing is not enabled.
1682 double max_heapbytes_used;
1683
1684 // Keep track of arguments to compute asymptotic complexity
1685 BigO complexity;
1686 BigOFunc* complexity_lambda;
1687 int64_t complexity_n;
1688
1689 // what statistics to compute from the measurements
1690 const std::vector<internal::Statistics>* statistics;
1691
1692 // Inform print function whether the current run is a complexity report
1693 bool report_big_o;
1694 bool report_rms;
1695
1696 UserCounters counters;
1697
1698 // Memory metrics.
1699 const MemoryManager::Result* memory_result;
1700 double allocs_per_iter;
1701 };
1702
1704 PerFamilyRunReports() : num_runs_total(0), num_runs_done(0) {}
1705
1706 // How many runs will all instances of this benchmark perform?
1707 int num_runs_total;
1708
1709 // How many runs have happened already?
1710 int num_runs_done;
1711
1712 // The reports about (non-errneous!) runs of this family.
1713 std::vector<BenchmarkReporter::Run> Runs;
1714 };
1715
1716 // Construct a BenchmarkReporter with the output stream set to 'std::cout'
1717 // and the error stream set to 'std::cerr'
1719
1720 // Called once for every suite of benchmarks run.
1721 // The parameter "context" contains information that the
1722 // reporter may wish to use when generating its report, for example the
1723 // platform under which the benchmarks are running. The benchmark run is
1724 // never started if this function returns false, allowing the reporter
1725 // to skip runs based on the context information.
1726 virtual bool ReportContext(const Context& context) = 0;
1727
1728 // Called once for each group of benchmark runs, gives information about
1729 // cpu-time and heap memory usage during the benchmark run. If the group
1730 // of runs contained more than two entries then 'report' contains additional
1731 // elements representing the mean and standard deviation of those runs.
1732 // Additionally if this group of runs was the last in a family of benchmarks
1733 // 'reports' contains additional entries representing the asymptotic
1734 // complexity and RMS of that benchmark family.
1735 virtual void ReportRuns(const std::vector<Run>& report) = 0;
1736
1737 // Called once and only once after ever group of benchmarks is run and
1738 // reported.
1739 virtual void Finalize() {}
1740
1741 // REQUIRES: The object referenced by 'out' is valid for the lifetime
1742 // of the reporter.
1743 void SetOutputStream(std::ostream* out) {
1744 assert(out);
1745 output_stream_ = out;
1746 }
1747
1748 // REQUIRES: The object referenced by 'err' is valid for the lifetime
1749 // of the reporter.
1750 void SetErrorStream(std::ostream* err) {
1751 assert(err);
1752 error_stream_ = err;
1753 }
1754
1755 std::ostream& GetOutputStream() const { return *output_stream_; }
1756
1757 std::ostream& GetErrorStream() const { return *error_stream_; }
1758
1759 virtual ~BenchmarkReporter();
1760
1761 // Write a human readable string to 'out' representing the specified
1762 // 'context'.
1763 // REQUIRES: 'out' is non-null.
1764 static void PrintBasicContext(std::ostream* out, Context const& context);
1765
1766 private:
1767 std::ostream* output_stream_;
1768 std::ostream* error_stream_;
1769};
1770
1771// Simple reporter that outputs benchmark data to the console. This is the
1772// default reporter used by RunSpecifiedBenchmarks().
1773class BENCHMARK_EXPORT ConsoleReporter : public BenchmarkReporter {
1774 public:
1775 enum OutputOptions {
1776 OO_None = 0,
1777 OO_Color = 1,
1778 OO_Tabular = 2,
1779 OO_ColorTabular = OO_Color | OO_Tabular,
1780 OO_Defaults = OO_ColorTabular
1781 };
1782 explicit ConsoleReporter(OutputOptions opts_ = OO_Defaults)
1783 : output_options_(opts_), name_field_width_(0), printed_header_(false) {}
1784
1785 virtual bool ReportContext(const Context& context) BENCHMARK_OVERRIDE;
1786 virtual void ReportRuns(const std::vector<Run>& reports) BENCHMARK_OVERRIDE;
1787
1788 protected:
1789 virtual void PrintRunData(const Run& report);
1790 virtual void PrintHeader(const Run& report);
1791
1792 OutputOptions output_options_;
1793 size_t name_field_width_;
1794 UserCounters prev_counters_;
1795 bool printed_header_;
1796};
1797
1798class BENCHMARK_EXPORT JSONReporter : public BenchmarkReporter {
1799 public:
1800 JSONReporter() : first_report_(true) {}
1801 virtual bool ReportContext(const Context& context) BENCHMARK_OVERRIDE;
1802 virtual void ReportRuns(const std::vector<Run>& reports) BENCHMARK_OVERRIDE;
1803 virtual void Finalize() BENCHMARK_OVERRIDE;
1804
1805 private:
1806 void PrintRunData(const Run& report);
1807
1808 bool first_report_;
1809};
1810
1811class BENCHMARK_EXPORT BENCHMARK_DEPRECATED_MSG(
1812 "The CSV Reporter will be removed in a future release") CSVReporter
1813 : public BenchmarkReporter {
1814 public:
1815 CSVReporter() : printed_header_(false) {}
1816 virtual bool ReportContext(const Context& context) BENCHMARK_OVERRIDE;
1817 virtual void ReportRuns(const std::vector<Run>& reports) BENCHMARK_OVERRIDE;
1818
1819 private:
1820 void PrintRunData(const Run& report);
1821
1822 bool printed_header_;
1823 std::set<std::string> user_counter_names_;
1824};
1825
1826inline const char* GetTimeUnitString(TimeUnit unit) {
1827 switch (unit) {
1828 case kSecond:
1829 return "s";
1830 case kMillisecond:
1831 return "ms";
1832 case kMicrosecond:
1833 return "us";
1834 case kNanosecond:
1835 return "ns";
1836 }
1837 BENCHMARK_UNREACHABLE();
1838}
1839
1840inline double GetTimeUnitMultiplier(TimeUnit unit) {
1841 switch (unit) {
1842 case kSecond:
1843 return 1;
1844 case kMillisecond:
1845 return 1e3;
1846 case kMicrosecond:
1847 return 1e6;
1848 case kNanosecond:
1849 return 1e9;
1850 }
1851 BENCHMARK_UNREACHABLE();
1852}
1853
1854// Creates a list of integer values for the given range and multiplier.
1855// This can be used together with ArgsProduct() to allow multiple ranges
1856// with different multiplers.
1857// Example:
1858// ArgsProduct({
1859// CreateRange(0, 1024, /*multi=*/32),
1860// CreateRange(0, 100, /*multi=*/4),
1861// CreateDenseRange(0, 4, /*step=*/1),
1862// });
1863BENCHMARK_EXPORT
1864std::vector<int64_t> CreateRange(int64_t lo, int64_t hi, int multi);
1865
1866// Creates a list of integer values for the given range and step.
1867BENCHMARK_EXPORT
1868std::vector<int64_t> CreateDenseRange(int64_t start, int64_t limit, int step);
1869
1870} // namespace benchmark
1871
1872#if defined(_MSC_VER)
1873#pragma warning(pop)
1874#endif
1875
1876#endif // BENCHMARK_BENCHMARK_H_
Definition: benchmark.h:1617
Definition: benchmark.h:1773
Definition: benchmark.h:539
Definition: benchmark.h:1316
Definition: benchmark.h:1798
Definition: benchmark.h:364
Definition: benchmark.h:656
Definition: benchmark_register.cc:73
Definition: benchmark_api_internal.h:18
Definition: benchmark.h:987
Definition: benchmark.h:1255
Definition: perf_counters.h:134
Definition: thread_manager.h:12
Definition: thread_timer.h:10
Definition: benchmark.h:1597
Definition: benchmark.h:1619
Definition: benchmark.h:1628
Definition: benchmark.h:1562
Definition: benchmark.h:1561
Definition: benchmark.h:368
Definition: benchmark.h:930
Definition: benchmark.h:929
Definition: benchmark.h:1585
Definition: benchmark.h:617