163#ifndef BENCHMARK_BENCHMARK_H_
164#define BENCHMARK_BENCHMARK_H_
173#include <initializer_list>
180#include <type_traits>
184#include "benchmark/export.h"
190#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \
191 TypeName(const TypeName&) = delete; \
192 TypeName& operator=(const TypeName&) = delete
194#ifdef BENCHMARK_HAS_CXX17
195#define BENCHMARK_UNUSED [[maybe_unused]]
196#elif defined(__GNUC__) || defined(__clang__)
197#define BENCHMARK_UNUSED __attribute__((unused))
199#define BENCHMARK_UNUSED
205#if defined(__clang__)
206#define BENCHMARK_DONT_OPTIMIZE __attribute__((optnone))
207#elif defined(__GNUC__) || defined(__GNUG__)
208#define BENCHMARK_DONT_OPTIMIZE __attribute__((optimize(0)))
211#define BENCHMARK_DONT_OPTIMIZE
214#if defined(__GNUC__) || defined(__clang__)
215#define BENCHMARK_ALWAYS_INLINE __attribute__((always_inline))
216#elif defined(_MSC_VER) && !defined(__clang__)
217#define BENCHMARK_ALWAYS_INLINE __forceinline
218#define __func__ __FUNCTION__
220#define BENCHMARK_ALWAYS_INLINE
223#define BENCHMARK_INTERNAL_TOSTRING2(x) #x
224#define BENCHMARK_INTERNAL_TOSTRING(x) BENCHMARK_INTERNAL_TOSTRING2(x)
227#if (defined(__GNUC__) && !defined(__NVCC__) && !defined(__NVCOMPILER)) || defined(__clang__)
228#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)
229#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
230#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
231 _Pragma("GCC diagnostic push") \
232 _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
233#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma("GCC diagnostic pop")
234#elif defined(__NVCOMPILER)
235#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)
236#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
237#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
238 _Pragma("diagnostic push") \
239 _Pragma("diag_suppress deprecated_entity_with_custom_message")
240#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma("diagnostic pop")
242#define BENCHMARK_BUILTIN_EXPECT(x, y) x
243#define BENCHMARK_DEPRECATED_MSG(msg)
244#define BENCHMARK_WARNING_MSG(msg) \
245 __pragma(message(__FILE__ "(" BENCHMARK_INTERNAL_TOSTRING( \
246 __LINE__) ") : warning note: " msg))
247#define BENCHMARK_DISABLE_DEPRECATED_WARNING
248#define BENCHMARK_RESTORE_DEPRECATED_WARNING
252#if defined(__GNUC__) && !defined(__clang__)
253#define BENCHMARK_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
257#define __has_builtin(x) 0
260#if defined(__GNUC__) || __has_builtin(__builtin_unreachable)
261#define BENCHMARK_UNREACHABLE() __builtin_unreachable()
262#elif defined(_MSC_VER)
263#define BENCHMARK_UNREACHABLE() __assume(false)
265#define BENCHMARK_UNREACHABLE() ((void)0)
270#if defined(__i386__) || defined(__x86_64__)
271#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
272#elif defined(__powerpc64__)
273#define BENCHMARK_INTERNAL_CACHELINE_SIZE 128
274#elif defined(__aarch64__)
275#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
276#elif defined(__arm__)
281#if defined(__ARM_ARCH_5T__)
282#define BENCHMARK_INTERNAL_CACHELINE_SIZE 32
283#elif defined(__ARM_ARCH_7A__)
284#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
289#ifndef BENCHMARK_INTERNAL_CACHELINE_SIZE
292#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
298#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED \
299 __attribute__((aligned(BENCHMARK_INTERNAL_CACHELINE_SIZE)))
300#elif defined(_MSC_VER)
301#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED \
302 __declspec(align(BENCHMARK_INTERNAL_CACHELINE_SIZE))
304#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED
310#pragma warning(disable : 4251)
316#if (__cplusplus < 201402L || (defined(_MSC_VER) && _MSVC_LANG < 201402L))
317template <
typename T,
typename... Args>
318std::unique_ptr<T> make_unique(Args&&... args) {
319 return std::unique_ptr<T>(
new T(std::forward<Args>(args)...));
322using ::std::make_unique;
329using IterationCount = int64_t;
332using callback_function = std::function<void(
const benchmark::State&)>;
335const char kDefaultMinTimeStr[] =
"0.5s";
338BENCHMARK_EXPORT std::string GetBenchmarkVersion();
340BENCHMARK_EXPORT
void PrintDefaultHelp();
342BENCHMARK_EXPORT
void Initialize(
int* argc,
char** argv,
343 void (*HelperPrintf)() = PrintDefaultHelp);
344BENCHMARK_EXPORT
void Shutdown();
348BENCHMARK_EXPORT
bool ReportUnrecognizedArguments(
int argc,
char** argv);
351BENCHMARK_EXPORT std::string GetBenchmarkFilter();
357BENCHMARK_EXPORT
void SetBenchmarkFilter(std::string value);
360BENCHMARK_EXPORT int32_t GetBenchmarkVerbosity();
383BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks();
384BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks(std::string spec);
386BENCHMARK_EXPORT
size_t
388BENCHMARK_EXPORT
size_t
391BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks(
393BENCHMARK_EXPORT
size_t
399enum TimeUnit { kNanosecond, kMicrosecond, kMillisecond, kSecond };
401BENCHMARK_EXPORT TimeUnit GetDefaultTimeUnit();
405BENCHMARK_EXPORT
void SetDefaultTimeUnit(TimeUnit unit);
412 static constexpr int64_t TombstoneValue = std::numeric_limits<int64_t>::max();
418 total_allocated_bytes(TombstoneValue),
419 net_heap_growth(TombstoneValue),
420 memory_iterations(0) {}
426 int64_t max_bytes_used;
430 int64_t total_allocated_bytes;
435 int64_t net_heap_growth;
437 IterationCount memory_iterations;
443 virtual void Start() = 0;
446 virtual void Stop(Result& result) = 0;
452void RegisterMemoryManager(MemoryManager* memory_manager);
462 virtual void AfterSetupStart() = 0;
466 virtual void BeforeTeardownStop() = 0;
476void AddCustomContext(
const std::string& key,
const std::string& value);
481class BenchmarkFamilies;
483BENCHMARK_EXPORT std::map<std::string, std::string>*& GetGlobalContext();
486void UseCharPointer(
char const volatile*);
490BENCHMARK_EXPORT Benchmark* RegisterBenchmarkInternal(
491 std::unique_ptr<Benchmark>);
494BENCHMARK_EXPORT
int InitializeStreams();
495BENCHMARK_UNUSED
static int stream_init_anchor = InitializeStreams();
499#if (!defined(__GNUC__) && !defined(__clang__)) || defined(__pnacl__) || \
500 defined(__EMSCRIPTEN__)
501#define BENCHMARK_HAS_NO_INLINE_ASSEMBLY
506inline BENCHMARK_ALWAYS_INLINE
void ClobberMemory() {
507 std::atomic_signal_fence(std::memory_order_acq_rel);
514#ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY
515#if !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER)
517BENCHMARK_DEPRECATED_MSG(
518 "The const-ref version of this method can permit "
519 "undesired compiler optimizations in benchmarks")
520inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
521 asm volatile(
"" : :
"r,m"(value) :
"memory");
525inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp& value) {
526#if defined(__clang__)
527 asm volatile(
"" :
"+r,m"(value) : :
"memory");
529 asm volatile(
"" :
"+m,r"(value) : :
"memory");
534inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp&& value) {
535#if defined(__clang__)
536 asm volatile(
"" :
"+r,m"(value) : :
"memory");
538 asm volatile(
"" :
"+m,r"(value) : :
"memory");
546BENCHMARK_DEPRECATED_MSG(
547 "The const-ref version of this method can permit "
548 "undesired compiler optimizations in benchmarks")
549inline BENCHMARK_ALWAYS_INLINE
550 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
551 (sizeof(Tp) <= sizeof(Tp*))>::type
552 DoNotOptimize(Tp const& value) {
553 asm volatile(
"" : :
"r,m"(value) :
"memory");
557BENCHMARK_DEPRECATED_MSG(
558 "The const-ref version of this method can permit "
559 "undesired compiler optimizations in benchmarks")
560inline BENCHMARK_ALWAYS_INLINE
561 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
562 (sizeof(Tp) > sizeof(Tp*))>::type
563 DoNotOptimize(Tp const& value) {
564 asm volatile(
"" : :
"m"(value) :
"memory");
568inline BENCHMARK_ALWAYS_INLINE
569 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
570 (
sizeof(Tp) <=
sizeof(Tp*))>::type
571 DoNotOptimize(Tp& value) {
572 asm volatile(
"" :
"+m,r"(value) : :
"memory");
576inline BENCHMARK_ALWAYS_INLINE
577 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
578 (
sizeof(Tp) >
sizeof(Tp*))>::type
579 DoNotOptimize(Tp& value) {
580 asm volatile(
"" :
"+m"(value) : :
"memory");
584inline BENCHMARK_ALWAYS_INLINE
585 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
586 (
sizeof(Tp) <=
sizeof(Tp*))>::type
587 DoNotOptimize(Tp&& value) {
588 asm volatile(
"" :
"+m,r"(value) : :
"memory");
592inline BENCHMARK_ALWAYS_INLINE
593 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
594 (
sizeof(Tp) >
sizeof(Tp*))>::type
595 DoNotOptimize(Tp&& value) {
596 asm volatile(
"" :
"+m"(value) : :
"memory");
601#elif defined(_MSC_VER)
603BENCHMARK_DEPRECATED_MSG(
604 "The const-ref version of this method can permit "
605 "undesired compiler optimizations in benchmarks")
606inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
607 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
613inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp&& value) {
614 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
629 kAvgThreads = 1 << 1,
631 kAvgThreadsRate = kIsRate | kAvgThreads,
634 kIsIterationInvariant = 1 << 2,
638 kIsIterationInvariantRate = kIsRate | kIsIterationInvariant,
641 kAvgIterations = 1 << 3,
643 kAvgIterationsRate = kIsRate | kAvgIterations,
660 BENCHMARK_ALWAYS_INLINE
661 Counter(
double v = 0., Flags f = kDefaults, OneK k = kIs1000)
662 : value(v), flags(f), oneK(k) {}
664 BENCHMARK_ALWAYS_INLINE
operator double const&()
const {
return value; }
665 BENCHMARK_ALWAYS_INLINE
operator double&() {
return value; }
670Counter::Flags
inline operator|(
const Counter::Flags& LHS,
671 const Counter::Flags& RHS) {
672 return static_cast<Counter::Flags
>(
static_cast<int>(LHS) |
673 static_cast<int>(RHS));
677typedef std::map<std::string, Counter> UserCounters;
683enum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLambda };
685typedef int64_t ComplexityN;
687enum StatisticUnit { kTime, kPercentage };
691typedef double(BigOFunc)(ComplexityN);
695typedef double(StatisticsFunc)(
const std::vector<double>&);
700 StatisticsFunc* compute_;
703 Statistics(
const std::string& name, StatisticsFunc* compute,
704 StatisticUnit unit = kTime)
705 : name_(name), compute_(compute), unit_(unit) {}
713enum AggregationReportMode :
unsigned {
718 ARM_Default = 1U << 0U,
720 ARM_FileReportAggregatesOnly = 1U << 1U,
722 ARM_DisplayReportAggregatesOnly = 1U << 2U,
724 ARM_ReportAggregatesOnly =
725 ARM_FileReportAggregatesOnly | ARM_DisplayReportAggregatesOnly
728enum Skipped :
unsigned {
739#pragma warning(disable : 4324)
743class BENCHMARK_EXPORT BENCHMARK_INTERNAL_CACHELINE_ALIGNED State {
761 inline bool KeepRunning();
773 inline bool KeepRunningBatch(IterationCount n);
822 void SkipWithMessage(
const std::string& msg);
843 void SkipWithError(
const std::string& msg);
846 bool skipped()
const {
return internal::NotSkipped != skipped_; }
849 bool error_occurred()
const {
return internal::SkippedWithError == skipped_; }
858 void SetIterationTime(
double seconds);
865 BENCHMARK_ALWAYS_INLINE
866 void SetBytesProcessed(int64_t bytes) {
867 counters[
"bytes_per_second"] =
868 Counter(
static_cast<double>(bytes), Counter::kIsRate, Counter::kIs1024);
871 BENCHMARK_ALWAYS_INLINE
872 int64_t bytes_processed()
const {
873 if (counters.find(
"bytes_per_second") != counters.end())
874 return static_cast<int64_t
>(counters.at(
"bytes_per_second"));
883 BENCHMARK_ALWAYS_INLINE
884 void SetComplexityN(ComplexityN complexity_n) {
885 complexity_n_ = complexity_n;
888 BENCHMARK_ALWAYS_INLINE
889 ComplexityN complexity_length_n()
const {
return complexity_n_; }
897 BENCHMARK_ALWAYS_INLINE
898 void SetItemsProcessed(int64_t items) {
899 counters[
"items_per_second"] =
900 Counter(
static_cast<double>(items), benchmark::Counter::kIsRate);
903 BENCHMARK_ALWAYS_INLINE
904 int64_t items_processed()
const {
905 if (counters.find(
"items_per_second") != counters.end())
906 return static_cast<int64_t
>(counters.at(
"items_per_second"));
922 void SetLabel(
const std::string& label);
925 BENCHMARK_ALWAYS_INLINE
926 int64_t range(std::size_t pos = 0)
const {
927 assert(range_.size() > pos);
931 BENCHMARK_DEPRECATED_MSG(
"use 'range(0)' instead")
932 int64_t range_x()
const {
return range(0); }
934 BENCHMARK_DEPRECATED_MSG(
"use 'range(1)' instead")
935 int64_t range_y()
const {
return range(1); }
938 BENCHMARK_ALWAYS_INLINE
939 int threads()
const {
return threads_; }
942 BENCHMARK_ALWAYS_INLINE
943 int thread_index()
const {
return thread_index_; }
945 BENCHMARK_ALWAYS_INLINE
946 IterationCount iterations()
const {
947 if (BENCHMARK_BUILTIN_EXPECT(!started_,
false)) {
950 return max_iterations - total_iterations_ + batch_leftover_;
953 BENCHMARK_ALWAYS_INLINE
954 std::string name()
const {
return name_; }
960 IterationCount total_iterations_;
965 IterationCount batch_leftover_;
968 const IterationCount max_iterations;
973 internal::Skipped skipped_;
976 std::vector<int64_t> range_;
978 ComplexityN complexity_n_;
982 UserCounters counters;
985 State(std::string name, IterationCount max_iters,
986 const std::vector<int64_t>& ranges,
int thread_i,
int n_threads,
991 void StartKeepRunning();
994 inline bool KeepRunningInternal(IterationCount n,
bool is_batch);
995 void FinishKeepRunning();
997 const std::string name_;
998 const int thread_index_;
1008#if defined(_MSC_VER)
1012inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunning() {
1013 return KeepRunningInternal(1,
false);
1016inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunningBatch(IterationCount n) {
1017 return KeepRunningInternal(n,
true);
1020inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunningInternal(IterationCount n,
1026 assert(is_batch || n == 1);
1027 if (BENCHMARK_BUILTIN_EXPECT(total_iterations_ >= n,
true)) {
1028 total_iterations_ -= n;
1033 if (!skipped() && total_iterations_ >= n) {
1034 total_iterations_ -= n;
1039 if (is_batch && total_iterations_ != 0) {
1040 batch_leftover_ = n - total_iterations_;
1041 total_iterations_ = 0;
1044 FinishKeepRunning();
1050 typedef std::forward_iterator_tag iterator_category;
1051 typedef Value value_type;
1052 typedef Value reference;
1053 typedef Value pointer;
1054 typedef std::ptrdiff_t difference_type;
1058 BENCHMARK_ALWAYS_INLINE
1059 StateIterator() : cached_(0), parent_() {}
1061 BENCHMARK_ALWAYS_INLINE
1063 : cached_(st->skipped() ? 0 : st->max_iterations), parent_(st) {}
1066 BENCHMARK_ALWAYS_INLINE
1067 Value operator*()
const {
return Value(); }
1069 BENCHMARK_ALWAYS_INLINE
1070 StateIterator& operator++() {
1071 assert(cached_ > 0);
1076 BENCHMARK_ALWAYS_INLINE
1077 bool operator!=(StateIterator
const&)
const {
1078 if (BENCHMARK_BUILTIN_EXPECT(cached_ != 0,
true))
return true;
1079 parent_->FinishKeepRunning();
1084 IterationCount cached_;
1085 State*
const parent_;
1098typedef void(Function)(State&);
1106class BENCHMARK_EXPORT Benchmark {
1108 virtual ~Benchmark();
1114 Benchmark* Name(
const std::string& name);
1119 Benchmark* Arg(int64_t x);
1122 Benchmark* Unit(TimeUnit unit);
1127 Benchmark* Range(int64_t start, int64_t limit);
1132 Benchmark* DenseRange(int64_t start, int64_t limit,
int step = 1);
1137 Benchmark* Args(
const std::vector<int64_t>& args);
1142 Benchmark* ArgPair(int64_t x, int64_t y) {
1143 std::vector<int64_t> args;
1152 Benchmark* Ranges(
const std::vector<std::pair<int64_t, int64_t>>& ranges);
1157 Benchmark* ArgsProduct(
const std::vector<std::vector<int64_t>>& arglists);
1160 Benchmark* ArgName(
const std::string& name);
1164 Benchmark* ArgNames(
const std::vector<std::string>& names);
1169 Benchmark* RangePair(int64_t lo1, int64_t hi1, int64_t lo2, int64_t hi2) {
1170 std::vector<std::pair<int64_t, int64_t>> ranges;
1171 ranges.push_back(std::make_pair(lo1, hi1));
1172 ranges.push_back(std::make_pair(lo2, hi2));
1173 return Ranges(ranges);
1188 Benchmark* Setup(callback_function&&);
1189 Benchmark* Setup(
const callback_function&);
1190 Benchmark* Teardown(callback_function&&);
1191 Benchmark* Teardown(
const callback_function&);
1196 Benchmark* Apply(
void (*custom_arguments)(Benchmark* benchmark));
1200 Benchmark* RangeMultiplier(
int multiplier);
1205 Benchmark* MinTime(
double t);
1211 Benchmark* MinWarmUpTime(
double t);
1220 Benchmark* Iterations(IterationCount n);
1225 Benchmark* Repetitions(
int n);
1231 Benchmark* ReportAggregatesOnly(
bool value =
true);
1234 Benchmark* DisplayAggregatesOnly(
bool value =
true);
1240 Benchmark* MeasureProcessCPUTime();
1248 Benchmark* UseRealTime();
1257 Benchmark* UseManualTime();
1261 Benchmark* Complexity(BigO complexity = benchmark::oAuto);
1265 Benchmark* Complexity(BigOFunc* complexity);
1268 Benchmark* ComputeStatistics(
const std::string& name,
1269 StatisticsFunc* statistics,
1270 StatisticUnit unit = kTime);
1277 Benchmark* Threads(
int t);
1291 Benchmark* ThreadRange(
int min_threads,
int max_threads);
1297 Benchmark* DenseThreadRange(
int min_threads,
int max_threads,
int stride = 1);
1300 Benchmark* ThreadPerCpu();
1302 virtual void Run(
State& state) = 0;
1304 TimeUnit GetTimeUnit()
const;
1307 explicit Benchmark(
const std::string& name);
1308 void SetName(
const std::string& name);
1311 const char* GetName()
const;
1312 int ArgsCnt()
const;
1313 const char* GetArgName(
int arg)
const;
1316 friend class BenchmarkFamilies;
1317 friend class BenchmarkInstance;
1320 AggregationReportMode aggregation_report_mode_;
1321 std::vector<std::string> arg_names_;
1322 std::vector<std::vector<int64_t>> args_;
1324 TimeUnit time_unit_;
1325 bool use_default_time_unit_;
1327 int range_multiplier_;
1329 double min_warmup_time_;
1330 IterationCount iterations_;
1332 bool measure_process_cpu_time_;
1333 bool use_real_time_;
1334 bool use_manual_time_;
1336 BigOFunc* complexity_lambda_;
1337 std::vector<Statistics> statistics_;
1338 std::vector<int> thread_counts_;
1340 callback_function setup_;
1341 callback_function teardown_;
1343 BENCHMARK_DISALLOW_COPY_AND_ASSIGN(Benchmark);
1353 internal::Function* fn);
1355template <
class Lambda>
1360BENCHMARK_EXPORT
void ClearRegisteredBenchmarks();
1365class BENCHMARK_EXPORT FunctionBenchmark :
public Benchmark {
1367 FunctionBenchmark(
const std::string& name, Function* func)
1368 : Benchmark(name), func_(func) {}
1370 void Run(
State& st)
override;
1376template <
class Lambda>
1377class LambdaBenchmark :
public Benchmark {
1379 void Run(
State& st)
override { lambda_(st); }
1381 template <
class OLambda>
1382 LambdaBenchmark(
const std::string& name, OLambda&& lam)
1383 : Benchmark(name), lambda_(std::forward<OLambda>(lam)) {}
1386 LambdaBenchmark(LambdaBenchmark
const&) =
delete;
1392 internal::Function* fn) {
1393 return internal::RegisterBenchmarkInternal(
1394 benchmark::internal::make_unique<internal::FunctionBenchmark>(name, fn));
1397template <
class Lambda>
1398internal::Benchmark* RegisterBenchmark(
const std::string& name, Lambda&& fn) {
1400 internal::LambdaBenchmark<typename std::decay<Lambda>::type>;
1401 return internal::RegisterBenchmarkInternal(
1402 benchmark::internal::make_unique<BenchType>(name,
1403 std::forward<Lambda>(fn)));
1406template <
class Lambda,
class... Args>
1409 return benchmark::RegisterBenchmark(
1410 name, [=](benchmark::State& st) { fn(st, args...); });
1418 void Run(
State& st)
override {
1420 this->BenchmarkCase(st);
1425 virtual void SetUp(
const State&) {}
1426 virtual void TearDown(
const State&) {}
1428 virtual void SetUp(
State& st) { SetUp(
const_cast<const State&
>(st)); }
1429 virtual void TearDown(
State& st) { TearDown(
const_cast<const State&
>(st)); }
1432 virtual void BenchmarkCase(
State&) = 0;
1442#if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0)
1443#define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__
1445#define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__
1449#define BENCHMARK_PRIVATE_NAME(...) \
1450 BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, \
1453#define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c)
1454#define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c
1456#define BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method) \
1457 BaseClass##_##Method##_Benchmark
1459#define BENCHMARK_PRIVATE_DECLARE(n) \
1461 static ::benchmark::internal::Benchmark const* const BENCHMARK_PRIVATE_NAME( \
1464#define BENCHMARK(...) \
1465 BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
1466 (::benchmark::internal::RegisterBenchmarkInternal( \
1467 benchmark::internal::make_unique< \
1468 ::benchmark::internal::FunctionBenchmark>(#__VA_ARGS__, \
1472#define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a))
1473#define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->Args({(a1), (a2)})
1474#define BENCHMARK_WITH_UNIT(n, t) BENCHMARK(n)->Unit((t))
1475#define BENCHMARK_RANGE(n, lo, hi) BENCHMARK(n)->Range((lo), (hi))
1476#define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \
1477 BENCHMARK(n)->RangePair({{(l1), (h1)}, {(l2), (h2)}})
1490#define BENCHMARK_CAPTURE(func, test_case_name, ...) \
1491 BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
1492 (::benchmark::internal::RegisterBenchmarkInternal( \
1493 benchmark::internal::make_unique< \
1494 ::benchmark::internal::FunctionBenchmark>( \
1495 #func "/" #test_case_name, \
1496 [](::benchmark::State& st) { func(st, __VA_ARGS__); })))
1506#define BENCHMARK_TEMPLATE1(n, a) \
1507 BENCHMARK_PRIVATE_DECLARE(n) = \
1508 (::benchmark::internal::RegisterBenchmarkInternal( \
1509 benchmark::internal::make_unique< \
1510 ::benchmark::internal::FunctionBenchmark>(#n "<" #a ">", n<a>)))
1512#define BENCHMARK_TEMPLATE2(n, a, b) \
1513 BENCHMARK_PRIVATE_DECLARE(n) = \
1514 (::benchmark::internal::RegisterBenchmarkInternal( \
1515 benchmark::internal::make_unique< \
1516 ::benchmark::internal::FunctionBenchmark>(#n "<" #a "," #b ">", \
1519#define BENCHMARK_TEMPLATE(n, ...) \
1520 BENCHMARK_PRIVATE_DECLARE(n) = \
1521 (::benchmark::internal::RegisterBenchmarkInternal( \
1522 benchmark::internal::make_unique< \
1523 ::benchmark::internal::FunctionBenchmark>( \
1524 #n "<" #__VA_ARGS__ ">", n<__VA_ARGS__>)))
1538#define BENCHMARK_TEMPLATE1_CAPTURE(func, a, test_case_name, ...) \
1539 BENCHMARK_CAPTURE(func<a>, test_case_name, __VA_ARGS__)
1541#define BENCHMARK_TEMPLATE2_CAPTURE(func, a, b, test_case_name, ...) \
1542 BENCHMARK_PRIVATE_DECLARE(func) = \
1543 (::benchmark::internal::RegisterBenchmarkInternal( \
1544 benchmark::internal::make_unique< \
1545 ::benchmark::internal::FunctionBenchmark>( \
1546 #func "<" #a "," #b ">" \
1547 "/" #test_case_name, \
1548 [](::benchmark::State& st) { func<a, b>(st, __VA_ARGS__); })))
1550#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1551 class BaseClass##_##Method##_Benchmark : public BaseClass { \
1553 BaseClass##_##Method##_Benchmark() { \
1554 this->SetName(#BaseClass "/" #Method); \
1558 void BenchmarkCase(::benchmark::State&) override; \
1561#define BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1562 class BaseClass##_##Method##_Benchmark : public BaseClass<a> { \
1564 BaseClass##_##Method##_Benchmark() { \
1565 this->SetName(#BaseClass "<" #a ">/" #Method); \
1569 void BenchmarkCase(::benchmark::State&) override; \
1572#define BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1573 class BaseClass##_##Method##_Benchmark : public BaseClass<a, b> { \
1575 BaseClass##_##Method##_Benchmark() { \
1576 this->SetName(#BaseClass "<" #a "," #b ">/" #Method); \
1580 void BenchmarkCase(::benchmark::State&) override; \
1583#define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, ...) \
1584 class BaseClass##_##Method##_Benchmark : public BaseClass<__VA_ARGS__> { \
1586 BaseClass##_##Method##_Benchmark() { \
1587 this->SetName(#BaseClass "<" #__VA_ARGS__ ">/" #Method); \
1591 void BenchmarkCase(::benchmark::State&) override; \
1594#define BENCHMARK_DEFINE_F(BaseClass, Method) \
1595 BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1596 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1598#define BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a) \
1599 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1600 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1602#define BENCHMARK_TEMPLATE2_DEFINE_F(BaseClass, Method, a, b) \
1603 BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1604 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1606#define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, ...) \
1607 BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \
1608 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1610#define BENCHMARK_REGISTER_F(BaseClass, Method) \
1611 BENCHMARK_PRIVATE_REGISTER_F(BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method))
1613#define BENCHMARK_PRIVATE_REGISTER_F(TestName) \
1614 BENCHMARK_PRIVATE_DECLARE(TestName) = \
1615 (::benchmark::internal::RegisterBenchmarkInternal( \
1616 benchmark::internal::make_unique<TestName>()))
1619#define BENCHMARK_F(BaseClass, Method) \
1620 BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1621 BENCHMARK_REGISTER_F(BaseClass, Method); \
1622 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1624#define BENCHMARK_TEMPLATE1_F(BaseClass, Method, a) \
1625 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1626 BENCHMARK_REGISTER_F(BaseClass, Method); \
1627 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1629#define BENCHMARK_TEMPLATE2_F(BaseClass, Method, a, b) \
1630 BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1631 BENCHMARK_REGISTER_F(BaseClass, Method); \
1632 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1634#define BENCHMARK_TEMPLATE_F(BaseClass, Method, ...) \
1635 BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \
1636 BENCHMARK_REGISTER_F(BaseClass, Method); \
1637 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1641#define BENCHMARK_MAIN() \
1642 int main(int argc, char** argv) { \
1643 char arg0_default[] = "benchmark"; \
1644 char* args_default = reinterpret_cast<char*>(arg0_default); \
1647 argv = &args_default; \
1649 ::benchmark::Initialize(&argc, argv); \
1650 if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; \
1651 ::benchmark::RunSpecifiedBenchmarks(); \
1652 ::benchmark::Shutdown(); \
1655 int main(int, char**)
1660namespace benchmark {
1662struct BENCHMARK_EXPORT CPUInfo {
1670 enum Scaling { UNKNOWN, ENABLED, DISABLED };
1674 double cycles_per_second;
1675 std::vector<CacheInfo> caches;
1676 std::vector<double> load_avg;
1682 BENCHMARK_DISALLOW_COPY_AND_ASSIGN(
CPUInfo);
1686struct BENCHMARK_EXPORT SystemInfo {
1688 static const SystemInfo& Get();
1692 BENCHMARK_DISALLOW_COPY_AND_ASSIGN(SystemInfo);
1699 std::string function_name;
1701 std::string min_time;
1702 std::string min_warmup_time;
1703 std::string iterations;
1704 std::string repetitions;
1705 std::string time_type;
1706 std::string threads;
1710 std::string str()
const;
1718class BENCHMARK_EXPORT BenchmarkReporter {
1724 size_t name_field_width = 0;
1725 static const char* executable_name;
1729 struct BENCHMARK_EXPORT Run {
1730 static const int64_t no_repetition_index = -1;
1731 enum RunType { RT_Iteration, RT_Aggregate };
1734 : run_type(RT_Iteration),
1735 aggregate_unit(kTime),
1736 skipped(internal::NotSkipped),
1739 time_unit(GetDefaultTimeUnit()),
1740 real_accumulated_time(0),
1741 cpu_accumulated_time(0),
1742 max_heapbytes_used(0),
1743 use_real_time_for_initial_big_o(
false),
1745 complexity_lambda(),
1747 report_big_o(
false),
1749 allocs_per_iter(0.0) {}
1751 std::string benchmark_name()
const;
1753 int64_t family_index;
1754 int64_t per_family_instance_index;
1756 std::string aggregate_name;
1757 StatisticUnit aggregate_unit;
1758 std::string report_label;
1759 internal::Skipped skipped;
1760 std::string skip_message;
1762 IterationCount iterations;
1764 int64_t repetition_index;
1765 int64_t repetitions;
1767 double real_accumulated_time;
1768 double cpu_accumulated_time;
1774 double GetAdjustedRealTime()
const;
1780 double GetAdjustedCPUTime()
const;
1783 double max_heapbytes_used;
1787 bool use_real_time_for_initial_big_o;
1791 BigOFunc* complexity_lambda;
1792 ComplexityN complexity_n;
1795 const std::vector<internal::Statistics>* statistics;
1801 UserCounters counters;
1805 double allocs_per_iter;
1808 struct PerFamilyRunReports {
1809 PerFamilyRunReports() : num_runs_total(0), num_runs_done(0) {}
1818 std::vector<BenchmarkReporter::Run> Runs;
1823 BenchmarkReporter();
1831 virtual bool ReportContext(
const Context& context) = 0;
1835 virtual void ReportRunsConfig(
double ,
1846 virtual void ReportRuns(
const std::vector<Run>& report) = 0;
1850 virtual void Finalize() {}
1854 void SetOutputStream(std::ostream* out) {
1856 output_stream_ = out;
1861 void SetErrorStream(std::ostream* err) {
1863 error_stream_ = err;
1866 std::ostream& GetOutputStream()
const {
return *output_stream_; }
1868 std::ostream& GetErrorStream()
const {
return *error_stream_; }
1870 virtual ~BenchmarkReporter();
1875 static void PrintBasicContext(std::ostream* out, Context
const& context);
1878 std::ostream* output_stream_;
1879 std::ostream* error_stream_;
1884class BENCHMARK_EXPORT ConsoleReporter :
public BenchmarkReporter {
1886 enum OutputOptions {
1890 OO_ColorTabular = OO_Color | OO_Tabular,
1891 OO_Defaults = OO_ColorTabular
1893 explicit ConsoleReporter(OutputOptions opts_ = OO_Defaults)
1894 : output_options_(opts_), name_field_width_(0), printed_header_(
false) {}
1896 bool ReportContext(
const Context& context)
override;
1897 void ReportRuns(
const std::vector<Run>& reports)
override;
1900 virtual void PrintRunData(
const Run& result);
1901 virtual void PrintHeader(
const Run& run);
1903 OutputOptions output_options_;
1904 size_t name_field_width_;
1905 UserCounters prev_counters_;
1906 bool printed_header_;
1909class BENCHMARK_EXPORT JSONReporter :
public BenchmarkReporter {
1911 JSONReporter() : first_report_(
true) {}
1912 bool ReportContext(
const Context& context)
override;
1913 void ReportRuns(
const std::vector<Run>& reports)
override;
1914 void Finalize()
override;
1917 void PrintRunData(
const Run& run);
1922class BENCHMARK_EXPORT BENCHMARK_DEPRECATED_MSG(
1923 "The CSV Reporter will be removed in a future release") CSVReporter
1926 CSVReporter() : printed_header_(false) {}
1927 bool ReportContext(
const Context& context)
override;
1928 void ReportRuns(
const std::vector<Run>& reports)
override;
1931 void PrintRunData(
const Run& run);
1933 bool printed_header_;
1934 std::set<std::string> user_counter_names_;
1937inline const char* GetTimeUnitString(TimeUnit unit) {
1948 BENCHMARK_UNREACHABLE();
1951inline double GetTimeUnitMultiplier(TimeUnit unit) {
1962 BENCHMARK_UNREACHABLE();
1975std::vector<int64_t> CreateRange(int64_t lo, int64_t hi,
int multi);
1979std::vector<int64_t> CreateDenseRange(int64_t start, int64_t limit,
int step);
1983#if defined(_MSC_VER)
Definition benchmark.h:1718
Definition benchmark.h:620
Definition benchmark.h:410
Definition benchmark.h:457
Definition benchmark.h:743
Definition benchmark_api_internal.h:18
Definition benchmark.h:1106
Definition perf_counters.h:149
Definition thread_manager.h:12
Definition thread_timer.h:10
Definition benchmark.h:1698
Definition benchmark.h:1720
Definition benchmark.h:1729
Definition benchmark.h:1663
Definition benchmark.h:1662
Definition benchmark.h:414
Definition benchmark.h:1049
Definition benchmark.h:1048
Definition benchmark.h:1686