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