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