163#ifndef BENCHMARK_BENCHMARK_H_
164#define BENCHMARK_BENCHMARK_H_
167#if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
168#define BENCHMARK_HAS_CXX11
172#if __cplusplus >= 201703L || \
173 (defined(_MSC_VER) && _MSC_VER >= 1911 && _MSVC_LANG >= 201703L)
174#define BENCHMARK_HAS_CXX17
190#include "benchmark/export.h"
192#if defined(BENCHMARK_HAS_CXX11)
194#include <initializer_list>
195#include <type_traits>
203#ifndef BENCHMARK_HAS_CXX11
204#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \
205 TypeName(const TypeName&); \
206 TypeName& operator=(const TypeName&)
208#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \
209 TypeName(const TypeName&) = delete; \
210 TypeName& operator=(const TypeName&) = delete
213#ifdef BENCHMARK_HAS_CXX17
214#define BENCHMARK_UNUSED [[maybe_unused]]
215#elif defined(__GNUC__) || defined(__clang__)
216#define BENCHMARK_UNUSED __attribute__((unused))
218#define BENCHMARK_UNUSED
224#if defined(__clang__)
225#define BENCHMARK_DONT_OPTIMIZE __attribute__((optnone))
226#elif defined(__GNUC__) || defined(__GNUG__)
227#define BENCHMARK_DONT_OPTIMIZE __attribute__((optimize(0)))
230#define BENCHMARK_DONT_OPTIMIZE
233#if defined(__GNUC__) || defined(__clang__)
234#define BENCHMARK_ALWAYS_INLINE __attribute__((always_inline))
235#elif defined(_MSC_VER) && !defined(__clang__)
236#define BENCHMARK_ALWAYS_INLINE __forceinline
237#define __func__ __FUNCTION__
239#define BENCHMARK_ALWAYS_INLINE
242#define BENCHMARK_INTERNAL_TOSTRING2(x) #x
243#define BENCHMARK_INTERNAL_TOSTRING(x) BENCHMARK_INTERNAL_TOSTRING2(x)
246#if (defined(__GNUC__) && !defined(__NVCC__) && !defined(__NVCOMPILER)) || defined(__clang__)
247#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)
248#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
249#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
250 _Pragma("GCC diagnostic push") \
251 _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
252#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma("GCC diagnostic pop")
253#elif defined(__NVCOMPILER)
254#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)
255#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
256#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
257 _Pragma("diagnostic push") \
258 _Pragma("diag_suppress deprecated_entity_with_custom_message")
259#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma("diagnostic pop")
261#define BENCHMARK_BUILTIN_EXPECT(x, y) x
262#define BENCHMARK_DEPRECATED_MSG(msg)
263#define BENCHMARK_WARNING_MSG(msg) \
264 __pragma(message(__FILE__ "(" BENCHMARK_INTERNAL_TOSTRING( \
265 __LINE__) ") : warning note: " msg))
266#define BENCHMARK_DISABLE_DEPRECATED_WARNING
267#define BENCHMARK_RESTORE_DEPRECATED_WARNING
271#if defined(__GNUC__) && !defined(__clang__)
272#define BENCHMARK_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
276#define __has_builtin(x) 0
279#if defined(__GNUC__) || __has_builtin(__builtin_unreachable)
280#define BENCHMARK_UNREACHABLE() __builtin_unreachable()
281#elif defined(_MSC_VER)
282#define BENCHMARK_UNREACHABLE() __assume(false)
284#define BENCHMARK_UNREACHABLE() ((void)0)
287#ifdef BENCHMARK_HAS_CXX11
288#define BENCHMARK_OVERRIDE override
290#define BENCHMARK_OVERRIDE
296#pragma warning(disable : 4251)
300class BenchmarkReporter;
303const char kDefaultMinTimeStr[] =
"0.5s";
306BENCHMARK_EXPORT std::string GetBenchmarkVersion();
308BENCHMARK_EXPORT
void PrintDefaultHelp();
310BENCHMARK_EXPORT
void Initialize(
int* argc,
char** argv,
311 void (*HelperPrinterf)() = PrintDefaultHelp);
312BENCHMARK_EXPORT
void Shutdown();
316BENCHMARK_EXPORT
bool ReportUnrecognizedArguments(
int argc,
char** argv);
319BENCHMARK_EXPORT std::string GetBenchmarkFilter();
325BENCHMARK_EXPORT
void SetBenchmarkFilter(std::string value);
328BENCHMARK_EXPORT int32_t GetBenchmarkVerbosity();
333BENCHMARK_EXPORT BenchmarkReporter* CreateDefaultDisplayReporter();
351BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks();
352BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks(std::string spec);
354BENCHMARK_EXPORT
size_t
355RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter);
356BENCHMARK_EXPORT
size_t
357RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, std::string spec);
359BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks(
360 BenchmarkReporter* display_reporter, BenchmarkReporter* file_reporter);
361BENCHMARK_EXPORT
size_t
362RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
363 BenchmarkReporter* file_reporter, std::string spec);
367enum TimeUnit { kNanosecond, kMicrosecond, kMillisecond, kSecond };
369BENCHMARK_EXPORT TimeUnit GetDefaultTimeUnit();
373BENCHMARK_EXPORT
void SetDefaultTimeUnit(TimeUnit unit);
380 static const int64_t TombstoneValue;
386 total_allocated_bytes(TombstoneValue),
387 net_heap_growth(TombstoneValue) {}
393 int64_t max_bytes_used;
397 int64_t total_allocated_bytes;
402 int64_t net_heap_growth;
408 virtual void Start() = 0;
411 virtual void Stop(Result& result) = 0;
417void RegisterMemoryManager(MemoryManager* memory_manager);
421void AddCustomContext(
const std::string& key,
const std::string& value);
426class BenchmarkFamilies;
428BENCHMARK_EXPORT std::map<std::string, std::string>*& GetGlobalContext();
431void UseCharPointer(
char const volatile*);
435BENCHMARK_EXPORT Benchmark* RegisterBenchmarkInternal(Benchmark*);
438BENCHMARK_EXPORT
int InitializeStreams();
439BENCHMARK_UNUSED
static int stream_init_anchor = InitializeStreams();
443#if (!defined(__GNUC__) && !defined(__clang__)) || defined(__pnacl__) || \
444 defined(__EMSCRIPTEN__)
445#define BENCHMARK_HAS_NO_INLINE_ASSEMBLY
450#ifdef BENCHMARK_HAS_CXX11
451inline BENCHMARK_ALWAYS_INLINE
void ClobberMemory() {
452 std::atomic_signal_fence(std::memory_order_acq_rel);
460#ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY
461#if !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER)
463BENCHMARK_DEPRECATED_MSG(
464 "The const-ref version of this method can permit "
465 "undesired compiler optimizations in benchmarks")
466inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
467 asm volatile(
"" : :
"r,m"(value) :
"memory");
471inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp& value) {
472#if defined(__clang__)
473 asm volatile(
"" :
"+r,m"(value) : :
"memory");
475 asm volatile(
"" :
"+m,r"(value) : :
"memory");
479#ifdef BENCHMARK_HAS_CXX11
481inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp&& value) {
482#if defined(__clang__)
483 asm volatile(
"" :
"+r,m"(value) : :
"memory");
485 asm volatile(
"" :
"+m,r"(value) : :
"memory");
489#elif defined(BENCHMARK_HAS_CXX11) && (__GNUC__ >= 5)
493BENCHMARK_DEPRECATED_MSG(
494 "The const-ref version of this method can permit "
495 "undesired compiler optimizations in benchmarks")
496inline BENCHMARK_ALWAYS_INLINE
497 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
498 (sizeof(Tp) <= sizeof(Tp*))>::type
499 DoNotOptimize(Tp const& value) {
500 asm volatile(
"" : :
"r,m"(value) :
"memory");
504BENCHMARK_DEPRECATED_MSG(
505 "The const-ref version of this method can permit "
506 "undesired compiler optimizations in benchmarks")
507inline BENCHMARK_ALWAYS_INLINE
508 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
509 (sizeof(Tp) > sizeof(Tp*))>::type
510 DoNotOptimize(Tp const& value) {
511 asm volatile(
"" : :
"m"(value) :
"memory");
515inline BENCHMARK_ALWAYS_INLINE
516 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
517 (
sizeof(Tp) <=
sizeof(Tp*))>::type
518 DoNotOptimize(Tp& value) {
519 asm volatile(
"" :
"+m,r"(value) : :
"memory");
523inline BENCHMARK_ALWAYS_INLINE
524 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
525 (
sizeof(Tp) >
sizeof(Tp*))>::type
526 DoNotOptimize(Tp& value) {
527 asm volatile(
"" :
"+m"(value) : :
"memory");
531inline BENCHMARK_ALWAYS_INLINE
532 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
533 (
sizeof(Tp) <=
sizeof(Tp*))>::type
534 DoNotOptimize(Tp&& value) {
535 asm volatile(
"" :
"+m,r"(value) : :
"memory");
539inline BENCHMARK_ALWAYS_INLINE
540 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
541 (
sizeof(Tp) >
sizeof(Tp*))>::type
542 DoNotOptimize(Tp&& value) {
543 asm volatile(
"" :
"+m"(value) : :
"memory");
551BENCHMARK_DEPRECATED_MSG(
552 "The const-ref version of this method can permit "
553 "undesired compiler optimizations in benchmarks")
554inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
555 asm volatile(
"" : :
"m"(value) :
"memory");
559inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp& value) {
560 asm volatile(
"" :
"+m"(value) : :
"memory");
563#ifdef BENCHMARK_HAS_CXX11
565inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp&& value) {
566 asm volatile(
"" :
"+m"(value) : :
"memory");
571#ifndef BENCHMARK_HAS_CXX11
572inline BENCHMARK_ALWAYS_INLINE
void ClobberMemory() {
573 asm volatile(
"" : : :
"memory");
576#elif defined(_MSC_VER)
578BENCHMARK_DEPRECATED_MSG(
579 "The const-ref version of this method can permit "
580 "undesired compiler optimizations in benchmarks")
581inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
582 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
586#ifndef BENCHMARK_HAS_CXX11
587inline BENCHMARK_ALWAYS_INLINE
void ClobberMemory() { _ReadWriteBarrier(); }
590#ifdef BENCHMARK_HAS_CXX11
592inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp&& value) {
593 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
597BENCHMARK_DEPRECATED_MSG(
598 "The const-ref version of this method can permit "
599 "undesired compiler optimizations in benchmarks")
600inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
601 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
605inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp& value) {
606 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
622 kAvgThreads = 1 << 1,
624 kAvgThreadsRate = kIsRate | kAvgThreads,
627 kIsIterationInvariant = 1 << 2,
631 kIsIterationInvariantRate = kIsRate | kIsIterationInvariant,
634 kAvgIterations = 1 << 3,
636 kAvgIterationsRate = kIsRate | kAvgIterations,
653 BENCHMARK_ALWAYS_INLINE
654 Counter(
double v = 0., Flags f = kDefaults, OneK k = kIs1000)
655 : value(v), flags(f), oneK(k) {}
657 BENCHMARK_ALWAYS_INLINE
operator double const &()
const {
return value; }
658 BENCHMARK_ALWAYS_INLINE
operator double&() {
return value; }
663Counter::Flags
inline operator|(
const Counter::Flags& LHS,
664 const Counter::Flags& RHS) {
665 return static_cast<Counter::Flags
>(
static_cast<int>(LHS) |
666 static_cast<int>(RHS));
670typedef std::map<std::string, Counter> UserCounters;
676enum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLambda };
678typedef int64_t ComplexityN;
680typedef int64_t IterationCount;
682enum StatisticUnit { kTime, kPercentage };
686typedef double(BigOFunc)(ComplexityN);
690typedef double(StatisticsFunc)(
const std::vector<double>&);
695 StatisticsFunc* compute_;
698 Statistics(
const std::string& name, StatisticsFunc* compute,
699 StatisticUnit unit = kTime)
700 : name_(name), compute_(compute), unit_(unit) {}
708enum AggregationReportMode
709#if defined(BENCHMARK_HAS_CXX11)
718 ARM_Default = 1U << 0U,
720 ARM_FileReportAggregatesOnly = 1U << 1U,
722 ARM_DisplayReportAggregatesOnly = 1U << 2U,
724 ARM_ReportAggregatesOnly =
725 ARM_FileReportAggregatesOnly | ARM_DisplayReportAggregatesOnly
729#if defined(BENCHMARK_HAS_CXX11)
760 inline bool KeepRunning();
772 inline bool KeepRunningBatch(IterationCount n);
821 void SkipWithMessage(
const std::string& msg);
842 void SkipWithError(
const std::string& msg);
845 bool skipped()
const {
return internal::NotSkipped != skipped_; }
848 bool error_occurred()
const {
return internal::SkippedWithError == skipped_; }
857 void SetIterationTime(
double seconds);
864 BENCHMARK_ALWAYS_INLINE
865 void SetBytesProcessed(int64_t bytes) {
866 counters[
"bytes_per_second"] =
867 Counter(
static_cast<double>(bytes), Counter::kIsRate, Counter::kIs1024);
870 BENCHMARK_ALWAYS_INLINE
871 int64_t bytes_processed()
const {
872 if (counters.find(
"bytes_per_second") != counters.end())
873 return static_cast<int64_t
>(counters.at(
"bytes_per_second"));
882 BENCHMARK_ALWAYS_INLINE
883 void SetComplexityN(ComplexityN complexity_n) {
884 complexity_n_ = complexity_n;
887 BENCHMARK_ALWAYS_INLINE
888 ComplexityN complexity_length_n()
const {
return complexity_n_; }
896 BENCHMARK_ALWAYS_INLINE
897 void SetItemsProcessed(int64_t items) {
898 counters[
"items_per_second"] =
899 Counter(
static_cast<double>(items), benchmark::Counter::kIsRate);
902 BENCHMARK_ALWAYS_INLINE
903 int64_t items_processed()
const {
904 if (counters.find(
"items_per_second") != counters.end())
905 return static_cast<int64_t
>(counters.at(
"items_per_second"));
921 void SetLabel(
const std::string& label);
924 BENCHMARK_ALWAYS_INLINE
925 int64_t range(std::size_t pos = 0)
const {
926 assert(range_.size() > pos);
930 BENCHMARK_DEPRECATED_MSG(
"use 'range(0)' instead")
931 int64_t range_x()
const {
return range(0); }
933 BENCHMARK_DEPRECATED_MSG(
"use 'range(1)' instead")
934 int64_t range_y()
const {
return range(1); }
937 BENCHMARK_ALWAYS_INLINE
938 int threads()
const {
return threads_; }
941 BENCHMARK_ALWAYS_INLINE
942 int thread_index()
const {
return thread_index_; }
944 BENCHMARK_ALWAYS_INLINE
945 IterationCount iterations()
const {
946 if (BENCHMARK_BUILTIN_EXPECT(!started_,
false)) {
949 return max_iterations - total_iterations_ + batch_leftover_;
952 BENCHMARK_ALWAYS_INLINE
953 std::string name()
const {
return name_; }
959 IterationCount total_iterations_;
964 IterationCount batch_leftover_;
967 const IterationCount max_iterations;
972 internal::Skipped skipped_;
975 std::vector<int64_t> range_;
977 ComplexityN complexity_n_;
981 UserCounters counters;
984 State(std::string name, IterationCount max_iters,
985 const std::vector<int64_t>& ranges,
int thread_i,
int n_threads,
989 void StartKeepRunning();
992 inline bool KeepRunningInternal(IterationCount n,
bool is_batch);
993 void FinishKeepRunning();
995 const std::string name_;
996 const int thread_index_;
1006inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunning() {
1007 return KeepRunningInternal(1,
false);
1010inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunningBatch(IterationCount n) {
1011 return KeepRunningInternal(n,
true);
1014inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunningInternal(IterationCount n,
1020 assert(is_batch || n == 1);
1021 if (BENCHMARK_BUILTIN_EXPECT(total_iterations_ >= n,
true)) {
1022 total_iterations_ -= n;
1027 if (!skipped() && total_iterations_ >= n) {
1028 total_iterations_ -= n;
1033 if (is_batch && total_iterations_ != 0) {
1034 batch_leftover_ = n - total_iterations_;
1035 total_iterations_ = 0;
1038 FinishKeepRunning();
1044 typedef std::forward_iterator_tag iterator_category;
1048 typedef std::ptrdiff_t difference_type;
1052 BENCHMARK_ALWAYS_INLINE
1055 BENCHMARK_ALWAYS_INLINE
1057 : cached_(st->skipped() ? 0 : st->max_iterations), parent_(st) {}
1060 BENCHMARK_ALWAYS_INLINE
1061 Value operator*()
const {
return Value(); }
1063 BENCHMARK_ALWAYS_INLINE
1064 StateIterator& operator++() {
1065 assert(cached_ > 0);
1070 BENCHMARK_ALWAYS_INLINE
1071 bool operator!=(StateIterator
const&)
const {
1072 if (BENCHMARK_BUILTIN_EXPECT(cached_ != 0,
true))
return true;
1073 parent_->FinishKeepRunning();
1078 IterationCount cached_;
1079 State*
const parent_;
1082inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::begin() {
1083 return StateIterator(
this);
1085inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::end() {
1087 return StateIterator();
1092typedef void(Function)(State&);
1108 Benchmark* Name(
const std::string& name);
1121 Benchmark* Range(int64_t start, int64_t limit);
1126 Benchmark* DenseRange(int64_t start, int64_t limit,
int step = 1);
1131 Benchmark* Args(
const std::vector<int64_t>& args);
1136 Benchmark* ArgPair(int64_t x, int64_t y) {
1137 std::vector<int64_t> args;
1146 Benchmark* Ranges(
const std::vector<std::pair<int64_t, int64_t> >& ranges);
1151 Benchmark* ArgsProduct(
const std::vector<std::vector<int64_t> >& arglists);
1154 Benchmark* ArgName(
const std::string& name);
1158 Benchmark* ArgNames(
const std::vector<std::string>& names);
1163 Benchmark* RangePair(int64_t lo1, int64_t hi1, int64_t lo2, int64_t hi2) {
1164 std::vector<std::pair<int64_t, int64_t> > ranges;
1165 ranges.push_back(std::make_pair(lo1, hi1));
1166 ranges.push_back(std::make_pair(lo2, hi2));
1167 return Ranges(ranges);
1194 Benchmark* RangeMultiplier(
int multiplier);
1214 Benchmark* Iterations(IterationCount n);
1225 Benchmark* ReportAggregatesOnly(
bool value =
true);
1228 Benchmark* DisplayAggregatesOnly(
bool value =
true);
1255 Benchmark* Complexity(BigO complexity = benchmark::oAuto);
1259 Benchmark* Complexity(BigOFunc* complexity);
1262 Benchmark* ComputeStatistics(
const std::string& name,
1263 StatisticsFunc* statistics,
1264 StatisticUnit unit = kTime);
1285 Benchmark* ThreadRange(
int min_threads,
int max_threads);
1291 Benchmark* DenseThreadRange(
int min_threads,
int max_threads,
int stride = 1);
1296 virtual void Run(
State& state) = 0;
1298 TimeUnit GetTimeUnit()
const;
1301 explicit Benchmark(
const std::string& name);
1302 void SetName(
const std::string& name);
1305 const char* GetName()
const;
1306 int ArgsCnt()
const;
1307 const char* GetArgName(
int arg)
const;
1314 AggregationReportMode aggregation_report_mode_;
1315 std::vector<std::string> arg_names_;
1316 std::vector<std::vector<int64_t> > args_;
1318 TimeUnit time_unit_;
1319 bool use_default_time_unit_;
1321 int range_multiplier_;
1323 double min_warmup_time_;
1324 IterationCount iterations_;
1326 bool measure_process_cpu_time_;
1327 bool use_real_time_;
1328 bool use_manual_time_;
1330 BigOFunc* complexity_lambda_;
1331 std::vector<Statistics> statistics_;
1332 std::vector<int> thread_counts_;
1335 callback_function setup_;
1336 callback_function teardown_;
1339#if defined(BENCHMARK_HAS_CXX11)
1345#if defined(BENCHMARK_HAS_CXX11)
1358 internal::Function* fn);
1360#if defined(BENCHMARK_HAS_CXX11)
1361template <
class Lambda>
1367BENCHMARK_EXPORT
void ClearRegisteredBenchmarks();
1377 void Run(
State& st) BENCHMARK_OVERRIDE;
1383#ifdef BENCHMARK_HAS_CXX11
1384template <
class Lambda>
1385class LambdaBenchmark :
public Benchmark {
1387 void Run(
State& st) BENCHMARK_OVERRIDE { lambda_(st); }
1390 template <
class OLambda>
1391 LambdaBenchmark(
const std::string& name, OLambda&& lam)
1392 : Benchmark(name), lambda_(std::forward<OLambda>(lam)) {}
1394 LambdaBenchmark(LambdaBenchmark
const&) =
delete;
1396 template <
class Lam>
1397 friend Benchmark* ::benchmark::RegisterBenchmark(
const std::string&, Lam&&);
1404inline internal::Benchmark* RegisterBenchmark(
const std::string& name,
1405 internal::Function* fn) {
1408 return internal::RegisterBenchmarkInternal(
1409 ::new internal::FunctionBenchmark(name, fn));
1412#ifdef BENCHMARK_HAS_CXX11
1413template <
class Lambda>
1414internal::Benchmark* RegisterBenchmark(
const std::string& name, Lambda&& fn) {
1416 internal::LambdaBenchmark<typename std::decay<Lambda>::type>;
1419 return internal::RegisterBenchmarkInternal(
1420 ::new BenchType(name, std::forward<Lambda>(fn)));
1424#if defined(BENCHMARK_HAS_CXX11) && \
1425 (!defined(BENCHMARK_GCC_VERSION) || BENCHMARK_GCC_VERSION >= 409)
1426template <
class Lambda,
class... Args>
1427internal::Benchmark* RegisterBenchmark(
const std::string& name, Lambda&& fn,
1429 return benchmark::RegisterBenchmark(
1433#define BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK
1441 void Run(
State& st) BENCHMARK_OVERRIDE {
1443 this->BenchmarkCase(st);
1448 virtual void SetUp(
const State&) {}
1449 virtual void TearDown(
const State&) {}
1451 virtual void SetUp(
State& st) { SetUp(
const_cast<const State&
>(st)); }
1452 virtual void TearDown(
State& st) { TearDown(
const_cast<const State&
>(st)); }
1455 virtual void BenchmarkCase(
State&) = 0;
1465#if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0)
1466#define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__
1468#define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__
1472#ifdef BENCHMARK_HAS_CXX11
1473#define BENCHMARK_PRIVATE_NAME(...) \
1474 BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, \
1477#define BENCHMARK_PRIVATE_NAME(n) \
1478 BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, n)
1481#define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c)
1482#define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c
1484#define BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method) \
1485 BaseClass##_##Method##_Benchmark
1487#define BENCHMARK_PRIVATE_DECLARE(n) \
1488 static ::benchmark::internal::Benchmark* BENCHMARK_PRIVATE_NAME(n) \
1491#ifdef BENCHMARK_HAS_CXX11
1492#define BENCHMARK(...) \
1493 BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
1494 (::benchmark::internal::RegisterBenchmarkInternal( \
1495 new ::benchmark::internal::FunctionBenchmark(#__VA_ARGS__, \
1498#define BENCHMARK(n) \
1499 BENCHMARK_PRIVATE_DECLARE(n) = \
1500 (::benchmark::internal::RegisterBenchmarkInternal( \
1501 new ::benchmark::internal::FunctionBenchmark(#n, n)))
1505#define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a))
1506#define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->Args({(a1), (a2)})
1507#define BENCHMARK_WITH_UNIT(n, t) BENCHMARK(n)->Unit((t))
1508#define BENCHMARK_RANGE(n, lo, hi) BENCHMARK(n)->Range((lo), (hi))
1509#define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \
1510 BENCHMARK(n)->RangePair({{(l1), (h1)}, {(l2), (h2)}})
1512#ifdef BENCHMARK_HAS_CXX11
1525#define BENCHMARK_CAPTURE(func, test_case_name, ...) \
1526 BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
1527 (::benchmark::internal::RegisterBenchmarkInternal( \
1528 new ::benchmark::internal::FunctionBenchmark( \
1529 #func "/" #test_case_name, \
1530 [](::benchmark::State& st) { func(st, __VA_ARGS__); })))
1542#define BENCHMARK_TEMPLATE1(n, a) \
1543 BENCHMARK_PRIVATE_DECLARE(n) = \
1544 (::benchmark::internal::RegisterBenchmarkInternal( \
1545 new ::benchmark::internal::FunctionBenchmark(#n "<" #a ">", n<a>)))
1547#define BENCHMARK_TEMPLATE2(n, a, b) \
1548 BENCHMARK_PRIVATE_DECLARE(n) = \
1549 (::benchmark::internal::RegisterBenchmarkInternal( \
1550 new ::benchmark::internal::FunctionBenchmark(#n "<" #a "," #b ">", \
1553#ifdef BENCHMARK_HAS_CXX11
1554#define BENCHMARK_TEMPLATE(n, ...) \
1555 BENCHMARK_PRIVATE_DECLARE(n) = \
1556 (::benchmark::internal::RegisterBenchmarkInternal( \
1557 new ::benchmark::internal::FunctionBenchmark( \
1558 #n "<" #__VA_ARGS__ ">", n<__VA_ARGS__>)))
1560#define BENCHMARK_TEMPLATE(n, a) BENCHMARK_TEMPLATE1(n, a)
1563#ifdef BENCHMARK_HAS_CXX11
1576#define BENCHMARK_TEMPLATE1_CAPTURE(func, a, test_case_name, ...) \
1577 BENCHMARK_CAPTURE(func<a>, test_case_name, __VA_ARGS__)
1579#define BENCHMARK_TEMPLATE2_CAPTURE(func, a, b, test_case_name, ...) \
1580 BENCHMARK_PRIVATE_DECLARE(func) = \
1581 (::benchmark::internal::RegisterBenchmarkInternal( \
1582 new ::benchmark::internal::FunctionBenchmark( \
1583 #func "<" #a "," #b ">" \
1584 "/" #test_case_name, \
1585 [](::benchmark::State& st) { func<a, b>(st, __VA_ARGS__); })))
1588#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1589 class BaseClass##_##Method##_Benchmark : public BaseClass { \
1591 BaseClass##_##Method##_Benchmark() { \
1592 this->SetName(#BaseClass "/" #Method); \
1596 void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \
1599#define BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1600 class BaseClass##_##Method##_Benchmark : public BaseClass<a> { \
1602 BaseClass##_##Method##_Benchmark() { \
1603 this->SetName(#BaseClass "<" #a ">/" #Method); \
1607 void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \
1610#define BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1611 class BaseClass##_##Method##_Benchmark : public BaseClass<a, b> { \
1613 BaseClass##_##Method##_Benchmark() { \
1614 this->SetName(#BaseClass "<" #a "," #b ">/" #Method); \
1618 void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \
1621#ifdef BENCHMARK_HAS_CXX11
1622#define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, ...) \
1623 class BaseClass##_##Method##_Benchmark : public BaseClass<__VA_ARGS__> { \
1625 BaseClass##_##Method##_Benchmark() { \
1626 this->SetName(#BaseClass "<" #__VA_ARGS__ ">/" #Method); \
1630 void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \
1633#define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(n, a) \
1634 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(n, a)
1637#define BENCHMARK_DEFINE_F(BaseClass, Method) \
1638 BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1639 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1641#define BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a) \
1642 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1643 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1645#define BENCHMARK_TEMPLATE2_DEFINE_F(BaseClass, Method, a, b) \
1646 BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1647 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1649#ifdef BENCHMARK_HAS_CXX11
1650#define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, ...) \
1651 BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \
1652 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1654#define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, a) \
1655 BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a)
1658#define BENCHMARK_REGISTER_F(BaseClass, Method) \
1659 BENCHMARK_PRIVATE_REGISTER_F(BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method))
1661#define BENCHMARK_PRIVATE_REGISTER_F(TestName) \
1662 BENCHMARK_PRIVATE_DECLARE(TestName) = \
1663 (::benchmark::internal::RegisterBenchmarkInternal(new TestName()))
1666#define BENCHMARK_F(BaseClass, Method) \
1667 BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1668 BENCHMARK_REGISTER_F(BaseClass, Method); \
1669 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1671#define BENCHMARK_TEMPLATE1_F(BaseClass, Method, a) \
1672 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1673 BENCHMARK_REGISTER_F(BaseClass, Method); \
1674 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1676#define BENCHMARK_TEMPLATE2_F(BaseClass, Method, a, b) \
1677 BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1678 BENCHMARK_REGISTER_F(BaseClass, Method); \
1679 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1681#ifdef BENCHMARK_HAS_CXX11
1682#define BENCHMARK_TEMPLATE_F(BaseClass, Method, ...) \
1683 BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \
1684 BENCHMARK_REGISTER_F(BaseClass, Method); \
1685 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1687#define BENCHMARK_TEMPLATE_F(BaseClass, Method, a) \
1688 BENCHMARK_TEMPLATE1_F(BaseClass, Method, a)
1693#define BENCHMARK_MAIN() \
1694 int main(int argc, char** argv) { \
1695 char arg0_default[] = "benchmark"; \
1696 char* args_default = arg0_default; \
1699 argv = &args_default; \
1701 ::benchmark::Initialize(&argc, argv); \
1702 if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; \
1703 ::benchmark::RunSpecifiedBenchmarks(); \
1704 ::benchmark::Shutdown(); \
1707 int main(int, char**)
1712namespace benchmark {
1722 enum Scaling { UNKNOWN, ENABLED, DISABLED };
1726 double cycles_per_second;
1727 std::vector<CacheInfo> caches;
1728 std::vector<double> load_avg;
1734 BENCHMARK_DISALLOW_COPY_AND_ASSIGN(
CPUInfo);
1744 BENCHMARK_DISALLOW_COPY_AND_ASSIGN(
SystemInfo);
1751 std::string function_name;
1753 std::string min_time;
1754 std::string min_warmup_time;
1755 std::string iterations;
1756 std::string repetitions;
1757 std::string time_type;
1758 std::string threads;
1762 std::string str()
const;
1776 size_t name_field_width;
1777 static const char* executable_name;
1782 static const int64_t no_repetition_index = -1;
1783 enum RunType { RT_Iteration, RT_Aggregate };
1786 : run_type(RT_Iteration),
1787 aggregate_unit(kTime),
1788 skipped(internal::NotSkipped),
1791 time_unit(GetDefaultTimeUnit()),
1792 real_accumulated_time(0),
1793 cpu_accumulated_time(0),
1794 max_heapbytes_used(0),
1795 use_real_time_for_initial_big_o(
false),
1797 complexity_lambda(),
1799 report_big_o(
false),
1801 memory_result(NULL),
1802 allocs_per_iter(0.0) {}
1804 std::string benchmark_name()
const;
1806 int64_t family_index;
1807 int64_t per_family_instance_index;
1809 std::string aggregate_name;
1810 StatisticUnit aggregate_unit;
1811 std::string report_label;
1812 internal::Skipped skipped;
1813 std::string skip_message;
1815 IterationCount iterations;
1817 int64_t repetition_index;
1818 int64_t repetitions;
1820 double real_accumulated_time;
1821 double cpu_accumulated_time;
1827 double GetAdjustedRealTime()
const;
1833 double GetAdjustedCPUTime()
const;
1836 double max_heapbytes_used;
1840 bool use_real_time_for_initial_big_o;
1844 BigOFunc* complexity_lambda;
1845 ComplexityN complexity_n;
1848 const std::vector<internal::Statistics>* statistics;
1854 UserCounters counters;
1858 double allocs_per_iter;
1871 std::vector<BenchmarkReporter::Run> Runs;
1884 virtual bool ReportContext(
const Context& context) = 0;
1888 virtual void ReportRunsConfig(
double ,
1899 virtual void ReportRuns(
const std::vector<Run>& report) = 0;
1903 virtual void Finalize() {}
1907 void SetOutputStream(std::ostream* out) {
1909 output_stream_ = out;
1914 void SetErrorStream(std::ostream* err) {
1916 error_stream_ = err;
1919 std::ostream& GetOutputStream()
const {
return *output_stream_; }
1921 std::ostream& GetErrorStream()
const {
return *error_stream_; }
1923 virtual ~BenchmarkReporter();
1928 static void PrintBasicContext(std::ostream* out, Context
const& context);
1931 std::ostream* output_stream_;
1932 std::ostream* error_stream_;
1939 enum OutputOptions {
1943 OO_ColorTabular = OO_Color | OO_Tabular,
1944 OO_Defaults = OO_ColorTabular
1947 : output_options_(opts_), name_field_width_(0), printed_header_(
false) {}
1949 bool ReportContext(
const Context& context) BENCHMARK_OVERRIDE;
1950 void ReportRuns(
const std::vector<Run>& reports) BENCHMARK_OVERRIDE;
1953 virtual void PrintRunData(
const Run& report);
1954 virtual void PrintHeader(
const Run& report);
1956 OutputOptions output_options_;
1957 size_t name_field_width_;
1958 UserCounters prev_counters_;
1959 bool printed_header_;
1965 bool ReportContext(
const Context& context) BENCHMARK_OVERRIDE;
1966 void ReportRuns(
const std::vector<Run>& reports) BENCHMARK_OVERRIDE;
1967 void Finalize() BENCHMARK_OVERRIDE;
1970 void PrintRunData(
const Run& report);
1975class BENCHMARK_EXPORT BENCHMARK_DEPRECATED_MSG(
1976 "The CSV Reporter will be removed in a future release") CSVReporter
1979 CSVReporter() : printed_header_(false) {}
1980 bool ReportContext(
const Context& context) BENCHMARK_OVERRIDE;
1981 void ReportRuns(
const std::vector<Run>& reports) BENCHMARK_OVERRIDE;
1984 void PrintRunData(
const Run& report);
1986 bool printed_header_;
1987 std::set<std::string> user_counter_names_;
1990inline const char* GetTimeUnitString(TimeUnit unit) {
2001 BENCHMARK_UNREACHABLE();
2004inline double GetTimeUnitMultiplier(TimeUnit unit) {
2015 BENCHMARK_UNREACHABLE();
2028std::vector<int64_t> CreateRange(int64_t lo, int64_t hi,
int multi);
2032std::vector<int64_t> CreateDenseRange(int64_t start, int64_t limit,
int step);
2036#if defined(_MSC_VER)
Definition benchmark.h:1770
Definition benchmark.h:1937
Definition benchmark.h:613
Definition benchmark.h:1437
Definition benchmark.h:1962
Definition benchmark.h:378
Definition benchmark.h:742
Definition benchmark_register.cc:73
Definition benchmark_api_internal.h:18
Definition benchmark.h:1100
Definition benchmark.h:1372
Definition perf_counters.h:149
Definition thread_manager.h:12
Definition thread_timer.h:10
Definition benchmark.h:1750
Definition benchmark.h:1772
Definition benchmark.h:1861
Definition benchmark.h:1781
Definition benchmark.h:1715
Definition benchmark.h:1714
Definition benchmark.h:382
Definition benchmark.h:1043
Definition benchmark.h:1042
Definition benchmark.h:1738
Definition benchmark.h:693