164#ifndef BENCHMARK_BENCHMARK_H_
165#define BENCHMARK_BENCHMARK_H_
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")
241#elif defined(_MSC_VER)
242#define BENCHMARK_BUILTIN_EXPECT(x, y) x
243#define BENCHMARK_DEPRECATED_MSG(msg) __declspec(deprecated(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 __pragma(warning(push)) \
249 __pragma(warning(disable : 4996))
250#define BENCHMARK_RESTORE_DEPRECATED_WARNING __pragma(warning(pop))
252#define BENCHMARK_BUILTIN_EXPECT(x, y) x
253#define BENCHMARK_DEPRECATED_MSG(msg)
254#define BENCHMARK_WARNING_MSG(msg) \
255 __pragma(message(__FILE__ "(" BENCHMARK_INTERNAL_TOSTRING( \
256 __LINE__) ") : warning note: " msg))
257#define BENCHMARK_DISABLE_DEPRECATED_WARNING
258#define BENCHMARK_RESTORE_DEPRECATED_WARNING
262#if defined(__GNUC__) && !defined(__clang__)
263#define BENCHMARK_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
267#define __has_builtin(x) 0
270#if defined(__GNUC__) || __has_builtin(__builtin_unreachable)
271#define BENCHMARK_UNREACHABLE() __builtin_unreachable()
272#elif defined(_MSC_VER)
273#define BENCHMARK_UNREACHABLE() __assume(false)
275#define BENCHMARK_UNREACHABLE() ((void)0)
280#if defined(__i386__) || defined(__x86_64__)
281#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
282#elif defined(__powerpc64__)
283#define BENCHMARK_INTERNAL_CACHELINE_SIZE 128
284#elif defined(__aarch64__)
285#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
286#elif defined(__arm__)
291#if defined(__ARM_ARCH_5T__)
292#define BENCHMARK_INTERNAL_CACHELINE_SIZE 32
293#elif defined(__ARM_ARCH_7A__)
294#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
299#ifndef BENCHMARK_INTERNAL_CACHELINE_SIZE
302#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
308#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED \
309 __attribute__((aligned(BENCHMARK_INTERNAL_CACHELINE_SIZE)))
310#elif defined(_MSC_VER)
311#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED \
312 __declspec(align(BENCHMARK_INTERNAL_CACHELINE_SIZE))
314#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED
320#pragma warning(disable : 4251)
326#if (__cplusplus < 201402L || (defined(_MSC_VER) && _MSVC_LANG < 201402L))
327template <
typename T,
typename... Args>
328std::unique_ptr<T> make_unique(Args&&... args) {
329 return std::unique_ptr<T>(
new T(std::forward<Args>(args)...));
332using ::std::make_unique;
339using IterationCount = int64_t;
342using callback_function = std::function<void(
const benchmark::State&)>;
345const char kDefaultMinTimeStr[] =
"0.5s";
347BENCHMARK_EXPORT
void MaybeReenterWithoutASLR(
int,
char**);
350BENCHMARK_EXPORT std::string GetBenchmarkVersion();
352BENCHMARK_EXPORT
void PrintDefaultHelp();
354BENCHMARK_EXPORT
void Initialize(
int* argc,
char** argv,
355 void (*HelperPrintf)() = PrintDefaultHelp);
356BENCHMARK_EXPORT
void Shutdown();
360BENCHMARK_EXPORT
bool ReportUnrecognizedArguments(
int argc,
char** argv);
363BENCHMARK_EXPORT std::string GetBenchmarkFilter();
369BENCHMARK_EXPORT
void SetBenchmarkFilter(std::string value);
372BENCHMARK_EXPORT int32_t GetBenchmarkVerbosity();
395BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks();
396BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks(std::string spec);
398BENCHMARK_EXPORT
size_t
400BENCHMARK_EXPORT
size_t
403BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks(
405BENCHMARK_EXPORT
size_t
411enum TimeUnit { kNanosecond, kMicrosecond, kMillisecond, kSecond };
413BENCHMARK_EXPORT TimeUnit GetDefaultTimeUnit();
417BENCHMARK_EXPORT
void SetDefaultTimeUnit(TimeUnit unit);
424 static constexpr int64_t TombstoneValue = std::numeric_limits<int64_t>::max();
430 total_allocated_bytes(TombstoneValue),
431 net_heap_growth(TombstoneValue),
432 memory_iterations(0) {}
438 int64_t max_bytes_used;
442 int64_t total_allocated_bytes;
447 int64_t net_heap_growth;
449 IterationCount memory_iterations;
455 virtual void Start() = 0;
458 virtual void Stop(Result& result) = 0;
464void RegisterMemoryManager(MemoryManager* memory_manager);
474 virtual void AfterSetupStart() = 0;
478 virtual void BeforeTeardownStop() = 0;
488void AddCustomContext(std::string key, std::string value);
494class BenchmarkFamilies;
496BENCHMARK_EXPORT std::map<std::string, std::string>*& GetGlobalContext();
499void UseCharPointer(
char const volatile*);
503BENCHMARK_EXPORT
Benchmark* RegisterBenchmarkInternal(
504 std::unique_ptr<Benchmark>);
507BENCHMARK_EXPORT
int InitializeStreams();
508BENCHMARK_UNUSED
static int stream_init_anchor = InitializeStreams();
512#if (!defined(__GNUC__) && !defined(__clang__)) || defined(__pnacl__) || \
513 defined(__EMSCRIPTEN__)
514#define BENCHMARK_HAS_NO_INLINE_ASSEMBLY
519inline BENCHMARK_ALWAYS_INLINE
void ClobberMemory() {
520 std::atomic_signal_fence(std::memory_order_acq_rel);
527#ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY
528#if !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER)
530BENCHMARK_DEPRECATED_MSG(
531 "The const-ref version of this method can permit "
532 "undesired compiler optimizations in benchmarks")
533inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
534 asm volatile(
"" : :
"r,m"(value) :
"memory");
538inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp& value) {
539#if defined(__clang__)
540 asm volatile(
"" :
"+r,m"(value) : :
"memory");
542 asm volatile(
"" :
"+m,r"(value) : :
"memory");
547inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp&& value) {
548#if defined(__clang__)
549 asm volatile(
"" :
"+r,m"(value) : :
"memory");
551 asm volatile(
"" :
"+m,r"(value) : :
"memory");
559BENCHMARK_DEPRECATED_MSG(
560 "The const-ref version of this method can permit "
561 "undesired compiler optimizations in benchmarks")
562inline BENCHMARK_ALWAYS_INLINE
563 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
564 (sizeof(Tp) <= sizeof(Tp*))>::type
565 DoNotOptimize(Tp const& value) {
566 asm volatile(
"" : :
"r,m"(value) :
"memory");
570BENCHMARK_DEPRECATED_MSG(
571 "The const-ref version of this method can permit "
572 "undesired compiler optimizations in benchmarks")
573inline BENCHMARK_ALWAYS_INLINE
574 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
575 (sizeof(Tp) > sizeof(Tp*))>::type
576 DoNotOptimize(Tp const& value) {
577 asm volatile(
"" : :
"m"(value) :
"memory");
581inline BENCHMARK_ALWAYS_INLINE
582 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
583 (
sizeof(Tp) <=
sizeof(Tp*))>::type
584 DoNotOptimize(Tp& value) {
585 asm volatile(
"" :
"+m,r"(value) : :
"memory");
589inline BENCHMARK_ALWAYS_INLINE
590 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
591 (
sizeof(Tp) >
sizeof(Tp*))>::type
592 DoNotOptimize(Tp& value) {
593 asm volatile(
"" :
"+m"(value) : :
"memory");
597inline BENCHMARK_ALWAYS_INLINE
598 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
599 (
sizeof(Tp) <=
sizeof(Tp*))>::type
600 DoNotOptimize(Tp&& value) {
601 asm volatile(
"" :
"+m,r"(value) : :
"memory");
605inline BENCHMARK_ALWAYS_INLINE
606 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
607 (
sizeof(Tp) >
sizeof(Tp*))>::type
608 DoNotOptimize(Tp&& value) {
609 asm volatile(
"" :
"+m"(value) : :
"memory");
614#elif defined(_MSC_VER)
616BENCHMARK_DEPRECATED_MSG(
617 "The const-ref version of this method can permit "
618 "undesired compiler optimizations in benchmarks")
619inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
620 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
625inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp& value) {
626 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
631inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp&& value) {
632 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
637inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp&& value) {
638 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
653 kAvgThreads = 1 << 1,
655 kAvgThreadsRate = kIsRate | kAvgThreads,
658 kIsIterationInvariant = 1 << 2,
662 kIsIterationInvariantRate = kIsRate | kIsIterationInvariant,
665 kAvgIterations = 1 << 3,
667 kAvgIterationsRate = kIsRate | kAvgIterations,
684 BENCHMARK_ALWAYS_INLINE
685 Counter(
double v = 0., Flags f = kDefaults, OneK k = kIs1000)
686 : value(v), flags(f), oneK(k) {}
688 BENCHMARK_ALWAYS_INLINE
operator double const&()
const {
return value; }
689 BENCHMARK_ALWAYS_INLINE
operator double&() {
return value; }
694Counter::Flags
inline operator|(
const Counter::Flags& LHS,
695 const Counter::Flags& RHS) {
696 return static_cast<Counter::Flags
>(
static_cast<int>(LHS) |
697 static_cast<int>(RHS));
701typedef std::map<std::string, Counter> UserCounters;
707enum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLambda };
709typedef int64_t ComplexityN;
711enum StatisticUnit { kTime, kPercentage };
715typedef double(BigOFunc)(ComplexityN);
719typedef double(StatisticsFunc)(
const std::vector<double>&);
724 StatisticsFunc* compute_;
727 Statistics(
const std::string& name, StatisticsFunc* compute,
728 StatisticUnit unit = kTime)
729 : name_(name), compute_(compute), unit_(unit) {}
737enum AggregationReportMode :
unsigned {
742 ARM_Default = 1U << 0U,
744 ARM_FileReportAggregatesOnly = 1U << 1U,
746 ARM_DisplayReportAggregatesOnly = 1U << 2U,
748 ARM_ReportAggregatesOnly =
749 ARM_FileReportAggregatesOnly | ARM_DisplayReportAggregatesOnly
752enum Skipped :
unsigned {
763#pragma warning(disable : 4324)
767class BENCHMARK_EXPORT BENCHMARK_INTERNAL_CACHELINE_ALIGNED State {
785 inline bool KeepRunning();
797 inline bool KeepRunningBatch(IterationCount n);
846 void SkipWithMessage(
const std::string& msg);
867 void SkipWithError(
const std::string& msg);
870 bool skipped()
const {
return internal::NotSkipped != skipped_; }
873 bool error_occurred()
const {
return internal::SkippedWithError == skipped_; }
882 void SetIterationTime(
double seconds);
889 BENCHMARK_ALWAYS_INLINE
890 void SetBytesProcessed(int64_t bytes) {
891 counters[
"bytes_per_second"] =
892 Counter(
static_cast<double>(bytes), Counter::kIsRate, Counter::kIs1024);
895 BENCHMARK_ALWAYS_INLINE
896 int64_t bytes_processed()
const {
897 if (counters.find(
"bytes_per_second") != counters.end())
898 return static_cast<int64_t
>(counters.at(
"bytes_per_second"));
907 BENCHMARK_ALWAYS_INLINE
908 void SetComplexityN(ComplexityN complexity_n) {
909 complexity_n_ = complexity_n;
912 BENCHMARK_ALWAYS_INLINE
913 ComplexityN complexity_length_n()
const {
return complexity_n_; }
921 BENCHMARK_ALWAYS_INLINE
922 void SetItemsProcessed(int64_t items) {
923 counters[
"items_per_second"] =
924 Counter(
static_cast<double>(items), benchmark::Counter::kIsRate);
927 BENCHMARK_ALWAYS_INLINE
928 int64_t items_processed()
const {
929 if (counters.find(
"items_per_second") != counters.end())
930 return static_cast<int64_t
>(counters.at(
"items_per_second"));
946 void SetLabel(
const std::string& label);
949 BENCHMARK_ALWAYS_INLINE
950 int64_t range(std::size_t pos = 0)
const {
951 assert(range_.size() > pos);
955 BENCHMARK_DEPRECATED_MSG(
"use 'range(0)' instead")
956 int64_t range_x()
const {
return range(0); }
958 BENCHMARK_DEPRECATED_MSG(
"use 'range(1)' instead")
959 int64_t range_y()
const {
return range(1); }
962 BENCHMARK_ALWAYS_INLINE
963 int threads()
const {
return threads_; }
966 BENCHMARK_ALWAYS_INLINE
967 int thread_index()
const {
return thread_index_; }
969 BENCHMARK_ALWAYS_INLINE
970 IterationCount iterations()
const {
971 if (BENCHMARK_BUILTIN_EXPECT(!started_,
false)) {
974 return max_iterations - total_iterations_ + batch_leftover_;
977 BENCHMARK_ALWAYS_INLINE
978 std::string name()
const {
return name_; }
980 size_t range_size()
const {
return range_.size(); }
986 IterationCount total_iterations_;
991 IterationCount batch_leftover_;
994 const IterationCount max_iterations;
999 internal::Skipped skipped_;
1002 std::vector<int64_t> range_;
1004 ComplexityN complexity_n_;
1008 UserCounters counters;
1011 State(std::string name, IterationCount max_iters,
1012 const std::vector<int64_t>& ranges,
int thread_i,
int n_threads,
1017 void StartKeepRunning();
1020 inline bool KeepRunningInternal(IterationCount n,
bool is_batch);
1021 void FinishKeepRunning();
1023 const std::string name_;
1024 const int thread_index_;
1034#if defined(_MSC_VER)
1038inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunning() {
1039 return KeepRunningInternal(1,
false);
1042inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunningBatch(IterationCount n) {
1043 return KeepRunningInternal(n,
true);
1046inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunningInternal(IterationCount n,
1052 assert(is_batch || n == 1);
1053 if (BENCHMARK_BUILTIN_EXPECT(total_iterations_ >= n,
true)) {
1054 total_iterations_ -= n;
1059 if (!skipped() && total_iterations_ >= n) {
1060 total_iterations_ -= n;
1065 if (is_batch && total_iterations_ != 0) {
1066 batch_leftover_ = n - total_iterations_;
1067 total_iterations_ = 0;
1070 FinishKeepRunning();
1076 typedef std::forward_iterator_tag iterator_category;
1077 typedef Value value_type;
1078 typedef Value reference;
1079 typedef Value pointer;
1080 typedef std::ptrdiff_t difference_type;
1084 BENCHMARK_ALWAYS_INLINE
1085 StateIterator() : cached_(0), parent_() {}
1087 BENCHMARK_ALWAYS_INLINE
1089 : cached_(st->skipped() ? 0 : st->max_iterations), parent_(st) {}
1092 BENCHMARK_ALWAYS_INLINE
1093 Value operator*()
const {
return Value(); }
1095 BENCHMARK_ALWAYS_INLINE
1096 StateIterator& operator++() {
1097 assert(cached_ > 0);
1102 BENCHMARK_ALWAYS_INLINE
1103 bool operator!=(StateIterator
const&)
const {
1104 if (BENCHMARK_BUILTIN_EXPECT(cached_ != 0,
true))
return true;
1105 parent_->FinishKeepRunning();
1110 IterationCount cached_;
1111 State*
const parent_;
1125 virtual void RunThreads(
const std::function<
void(
int)>& fn) = 0;
1129using threadrunner_factory =
1130 std::function<std::unique_ptr<ThreadRunnerBase>(
int)>;
1137class BENCHMARK_EXPORT Benchmark {
1139 virtual ~Benchmark();
1145 Benchmark* Name(
const std::string& name);
1150 Benchmark* Arg(int64_t x);
1153 Benchmark* Unit(TimeUnit unit);
1158 Benchmark* Range(int64_t start, int64_t limit);
1163 Benchmark* DenseRange(int64_t start, int64_t limit,
int step = 1);
1168 Benchmark* Args(
const std::vector<int64_t>& args);
1173 Benchmark* ArgPair(int64_t x, int64_t y) {
1174 std::vector<int64_t> args;
1183 Benchmark* Ranges(
const std::vector<std::pair<int64_t, int64_t>>& ranges);
1188 Benchmark* ArgsProduct(
const std::vector<std::vector<int64_t>>& arglists);
1191 Benchmark* ArgName(
const std::string& name);
1195 Benchmark* ArgNames(
const std::vector<std::string>& names);
1200 Benchmark* RangePair(int64_t lo1, int64_t hi1, int64_t lo2, int64_t hi2) {
1201 std::vector<std::pair<int64_t, int64_t>> ranges;
1202 ranges.push_back(std::make_pair(lo1, hi1));
1203 ranges.push_back(std::make_pair(lo2, hi2));
1204 return Ranges(ranges);
1219 Benchmark* Setup(callback_function&&);
1220 Benchmark* Setup(
const callback_function&);
1221 Benchmark* Teardown(callback_function&&);
1222 Benchmark* Teardown(
const callback_function&);
1227 Benchmark* Apply(
const std::function<
void(Benchmark* benchmark)>&);
1231 Benchmark* RangeMultiplier(
int multiplier);
1236 Benchmark* MinTime(
double t);
1242 Benchmark* MinWarmUpTime(
double t);
1251 Benchmark* Iterations(IterationCount n);
1256 Benchmark* Repetitions(
int n);
1262 Benchmark* ReportAggregatesOnly(
bool value =
true);
1265 Benchmark* DisplayAggregatesOnly(
bool value =
true);
1271 Benchmark* MeasureProcessCPUTime();
1279 Benchmark* UseRealTime();
1288 Benchmark* UseManualTime();
1292 Benchmark* Complexity(BigO complexity = benchmark::oAuto);
1296 Benchmark* Complexity(BigOFunc* complexity);
1299 Benchmark* ComputeStatistics(
const std::string& name,
1300 StatisticsFunc* statistics,
1301 StatisticUnit unit = kTime);
1308 Benchmark* Threads(
int t);
1322 Benchmark* ThreadRange(
int min_threads,
int max_threads);
1328 Benchmark* DenseThreadRange(
int min_threads,
int max_threads,
int stride = 1);
1331 Benchmark* ThreadPerCpu();
1334 Benchmark* ThreadRunner(threadrunner_factory&& factory);
1336 virtual void Run(
State& state) = 0;
1338 TimeUnit GetTimeUnit()
const;
1341 explicit Benchmark(
const std::string& name);
1342 void SetName(
const std::string& name);
1345 const char* GetName()
const;
1346 int ArgsCnt()
const;
1347 const char* GetArgName(
int arg)
const;
1354 internal::AggregationReportMode aggregation_report_mode_;
1355 std::vector<std::string> arg_names_;
1356 std::vector<std::vector<int64_t>> args_;
1358 TimeUnit time_unit_;
1359 bool use_default_time_unit_;
1361 int range_multiplier_;
1363 double min_warmup_time_;
1364 IterationCount iterations_;
1366 bool measure_process_cpu_time_;
1367 bool use_real_time_;
1368 bool use_manual_time_;
1370 BigOFunc* complexity_lambda_;
1371 std::vector<internal::Statistics> statistics_;
1372 std::vector<int> thread_counts_;
1374 callback_function setup_;
1375 callback_function teardown_;
1377 threadrunner_factory threadrunner_;
1379 BENCHMARK_DISALLOW_COPY_AND_ASSIGN(Benchmark);
1385typedef BENCHMARK_DEPRECATED_MSG(
"Use ::benchmark::Benchmark instead")
1387typedef BENCHMARK_DEPRECATED_MSG(
1388 "Use ::benchmark::threadrunner_factory instead")
1389 ::benchmark::threadrunner_factory threadrunner_factory;
1392typedef void(Function)(
State&);
1400Benchmark* RegisterBenchmark(
const std::string& name, internal::Function* fn);
1402template <
class Lambda>
1403Benchmark* RegisterBenchmark(
const std::string& name, Lambda&& fn);
1407BENCHMARK_EXPORT
void ClearRegisteredBenchmarks();
1414 FunctionBenchmark(
const std::string& name, Function* func)
1415 : Benchmark(name), func_(func) {}
1417 void Run(
State& st)
override;
1423template <
class Lambda>
1426 void Run(
State& st)
override { lambda_(st); }
1428 template <
class OLambda>
1429 LambdaBenchmark(
const std::string& name, OLambda&& lam)
1430 : Benchmark(name), lambda_(std::forward<OLambda>(lam)) {}
1433 LambdaBenchmark(LambdaBenchmark
const&) =
delete;
1438inline Benchmark* RegisterBenchmark(
const std::string& name,
1439 internal::Function* fn) {
1440 return internal::RegisterBenchmarkInternal(
1441 ::benchmark::internal::make_unique<internal::FunctionBenchmark>(name,
1445template <
class Lambda>
1446Benchmark* RegisterBenchmark(
const std::string& name, Lambda&& fn) {
1448 internal::LambdaBenchmark<typename std::decay<Lambda>::type>;
1449 return internal::RegisterBenchmarkInternal(
1450 ::benchmark::internal::make_unique<BenchType>(name,
1451 std::forward<Lambda>(fn)));
1454template <
class Lambda,
class... Args>
1455Benchmark* RegisterBenchmark(
const std::string& name, Lambda&& fn,
1457 return benchmark::RegisterBenchmark(
1458 name, [=](benchmark::State& st) { fn(st, args...); });
1462class Fixture :
public Benchmark {
1464 Fixture() : Benchmark(
"") {}
1466 void Run(
State& st)
override {
1468 this->BenchmarkCase(st);
1473 virtual void SetUp(
const State&) {}
1474 virtual void TearDown(
const State&) {}
1476 virtual void SetUp(
State& st) { SetUp(
const_cast<const State&
>(st)); }
1477 virtual void TearDown(
State& st) { TearDown(
const_cast<const State&
>(st)); }
1480 virtual void BenchmarkCase(
State&) = 0;
1488#if defined(__clang__)
1489#define BENCHMARK_DISABLE_COUNTER_WARNING \
1490 _Pragma("GCC diagnostic push") \
1491 _Pragma("GCC diagnostic ignored \"-Wunknown-warning-option\"") \
1492 _Pragma("GCC diagnostic ignored \"-Wc2y-extensions\"")
1493#define BENCHMARK_RESTORE_COUNTER_WARNING _Pragma("GCC diagnostic pop")
1495#define BENCHMARK_DISABLE_COUNTER_WARNING
1496#define BENCHMARK_RESTORE_COUNTER_WARNING
1503BENCHMARK_DISABLE_COUNTER_WARNING
1504#if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0)
1505#define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__
1507#define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__
1509BENCHMARK_RESTORE_COUNTER_WARNING
1512#define BENCHMARK_PRIVATE_NAME(...) \
1513 BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, \
1516#define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c)
1517#define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c
1519#define BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method) \
1520 BaseClass##_##Method##_Benchmark
1522#define BENCHMARK_PRIVATE_DECLARE(n) \
1523 BENCHMARK_DISABLE_COUNTER_WARNING \
1525 static ::benchmark::Benchmark const* const BENCHMARK_PRIVATE_NAME(n) \
1526 BENCHMARK_RESTORE_COUNTER_WARNING BENCHMARK_UNUSED
1528#define BENCHMARK(...) \
1529 BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
1530 (::benchmark::internal::RegisterBenchmarkInternal( \
1531 ::benchmark::internal::make_unique< \
1532 ::benchmark::internal::FunctionBenchmark>( \
1534 static_cast<::benchmark::internal::Function*>(__VA_ARGS__))))
1537#define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a))
1538#define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->Args({(a1), (a2)})
1539#define BENCHMARK_WITH_UNIT(n, t) BENCHMARK(n)->Unit((t))
1540#define BENCHMARK_RANGE(n, lo, hi) BENCHMARK(n)->Range((lo), (hi))
1541#define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \
1542 BENCHMARK(n)->RangePair({{(l1), (h1)}, {(l2), (h2)}})
1555#define BENCHMARK_CAPTURE(func, test_case_name, ...) \
1556 BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
1557 (::benchmark::internal::RegisterBenchmarkInternal( \
1558 ::benchmark::internal::make_unique< \
1559 ::benchmark::internal::FunctionBenchmark>( \
1560 #func "/" #test_case_name, \
1561 [](::benchmark::State& st) { func(st, __VA_ARGS__); })))
1571#define BENCHMARK_TEMPLATE1(n, a) \
1572 BENCHMARK_PRIVATE_DECLARE(n) = \
1573 (::benchmark::internal::RegisterBenchmarkInternal( \
1574 ::benchmark::internal::make_unique< \
1575 ::benchmark::internal::FunctionBenchmark>( \
1577 static_cast<::benchmark::internal::Function*>(n<a>))))
1579#define BENCHMARK_TEMPLATE2(n, a, b) \
1580 BENCHMARK_PRIVATE_DECLARE(n) = \
1581 (::benchmark::internal::RegisterBenchmarkInternal( \
1582 ::benchmark::internal::make_unique< \
1583 ::benchmark::internal::FunctionBenchmark>( \
1584 #n "<" #a "," #b ">", \
1585 static_cast<::benchmark::internal::Function*>(n<a, b>))))
1587#define BENCHMARK_TEMPLATE(n, ...) \
1588 BENCHMARK_PRIVATE_DECLARE(n) = \
1589 (::benchmark::internal::RegisterBenchmarkInternal( \
1590 ::benchmark::internal::make_unique< \
1591 ::benchmark::internal::FunctionBenchmark>( \
1592 #n "<" #__VA_ARGS__ ">", \
1593 static_cast<::benchmark::internal::Function*>(n<__VA_ARGS__>))))
1607#define BENCHMARK_TEMPLATE1_CAPTURE(func, a, test_case_name, ...) \
1608 BENCHMARK_CAPTURE(func<a>, test_case_name, __VA_ARGS__)
1610#define BENCHMARK_TEMPLATE2_CAPTURE(func, a, b, test_case_name, ...) \
1611 BENCHMARK_PRIVATE_DECLARE(func) = \
1612 (::benchmark::internal::RegisterBenchmarkInternal( \
1613 ::benchmark::internal::make_unique< \
1614 ::benchmark::internal::FunctionBenchmark>( \
1615 #func "<" #a "," #b ">" \
1616 "/" #test_case_name, \
1617 [](::benchmark::State& st) { func<a, b>(st, __VA_ARGS__); })))
1619#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1620 class BaseClass##_##Method##_Benchmark : public BaseClass { \
1622 BaseClass##_##Method##_Benchmark() { \
1623 this->SetName(#BaseClass "/" #Method); \
1627 void BenchmarkCase(::benchmark::State&) override; \
1630#define BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1631 class BaseClass##_##Method##_Benchmark : public BaseClass<a> { \
1633 BaseClass##_##Method##_Benchmark() { \
1634 this->SetName(#BaseClass "<" #a ">/" #Method); \
1638 void BenchmarkCase(::benchmark::State&) override; \
1641#define BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1642 class BaseClass##_##Method##_Benchmark : public BaseClass<a, b> { \
1644 BaseClass##_##Method##_Benchmark() { \
1645 this->SetName(#BaseClass "<" #a "," #b ">/" #Method); \
1649 void BenchmarkCase(::benchmark::State&) override; \
1652#define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, ...) \
1653 class BaseClass##_##Method##_Benchmark : public BaseClass<__VA_ARGS__> { \
1655 BaseClass##_##Method##_Benchmark() { \
1656 this->SetName(#BaseClass "<" #__VA_ARGS__ ">/" #Method); \
1660 void BenchmarkCase(::benchmark::State&) override; \
1663#define BENCHMARK_DEFINE_F(BaseClass, Method) \
1664 BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1665 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1667#define BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a) \
1668 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1669 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1671#define BENCHMARK_TEMPLATE2_DEFINE_F(BaseClass, Method, a, b) \
1672 BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1673 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1675#define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, ...) \
1676 BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \
1677 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1679#define BENCHMARK_REGISTER_F(BaseClass, Method) \
1680 BENCHMARK_PRIVATE_REGISTER_F(BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method))
1682#define BENCHMARK_PRIVATE_REGISTER_F(TestName) \
1683 BENCHMARK_PRIVATE_DECLARE(TestName) = \
1684 (::benchmark::internal::RegisterBenchmarkInternal( \
1685 ::benchmark::internal::make_unique<TestName>()))
1687#define BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F(BaseClass, Method) \
1688 BaseClass##_##Method##_BenchmarkTemplate
1690#define BENCHMARK_TEMPLATE_METHOD_F(BaseClass, Method) \
1691 template <class... Args> \
1692 class BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F(BaseClass, Method) \
1693 : public BaseClass<Args...> { \
1695 using Base = BaseClass<Args...>; \
1696 void BenchmarkCase(::benchmark::State&) override; \
1698 template <class... Args> \
1699 void BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F( \
1700 BaseClass, Method)<Args...>::BenchmarkCase
1702#define BENCHMARK_TEMPLATE_PRIVATE_INSTANTIATE_F(BaseClass, Method, \
1704 class UniqueName : public BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F( \
1705 BaseClass, Method)<__VA_ARGS__> { \
1707 UniqueName() { this->SetName(#BaseClass "<" #__VA_ARGS__ ">/" #Method); } \
1709 BENCHMARK_PRIVATE_DECLARE(BaseClass##_##Method##_Benchmark) = \
1710 (::benchmark::internal::RegisterBenchmarkInternal( \
1711 ::benchmark::internal::make_unique<UniqueName>()))
1713#define BENCHMARK_TEMPLATE_INSTANTIATE_F(BaseClass, Method, ...) \
1714 BENCHMARK_DISABLE_COUNTER_WARNING \
1715 BENCHMARK_TEMPLATE_PRIVATE_INSTANTIATE_F( \
1716 BaseClass, Method, BENCHMARK_PRIVATE_NAME(BaseClass##Method), \
1718 BENCHMARK_RESTORE_COUNTER_WARNING
1721#define BENCHMARK_F(BaseClass, Method) \
1722 BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1723 BENCHMARK_REGISTER_F(BaseClass, Method); \
1724 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1726#define BENCHMARK_TEMPLATE1_F(BaseClass, Method, a) \
1727 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1728 BENCHMARK_REGISTER_F(BaseClass, Method); \
1729 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1731#define BENCHMARK_TEMPLATE2_F(BaseClass, Method, a, b) \
1732 BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1733 BENCHMARK_REGISTER_F(BaseClass, Method); \
1734 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1736#define BENCHMARK_TEMPLATE_F(BaseClass, Method, ...) \
1737 BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \
1738 BENCHMARK_REGISTER_F(BaseClass, Method); \
1739 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1743#define BENCHMARK_MAIN() \
1744 int main(int argc, char** argv) { \
1745 benchmark::MaybeReenterWithoutASLR(argc, argv); \
1746 char arg0_default[] = "benchmark"; \
1747 char* args_default = reinterpret_cast<char*>(arg0_default); \
1750 argv = &args_default; \
1752 ::benchmark::Initialize(&argc, argv); \
1753 if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; \
1754 ::benchmark::RunSpecifiedBenchmarks(); \
1755 ::benchmark::Shutdown(); \
1758 int main(int, char**)
1763namespace benchmark {
1765struct BENCHMARK_EXPORT CPUInfo {
1773 enum Scaling { UNKNOWN, ENABLED, DISABLED };
1777 double cycles_per_second;
1778 std::vector<CacheInfo> caches;
1779 std::vector<double> load_avg;
1785 BENCHMARK_DISALLOW_COPY_AND_ASSIGN(
CPUInfo);
1789struct BENCHMARK_EXPORT SystemInfo {
1790 enum class ASLR { UNKNOWN, ENABLED, DISABLED };
1794 static const SystemInfo& Get();
1798 BENCHMARK_DISALLOW_COPY_AND_ASSIGN(SystemInfo);
1805 std::string function_name;
1807 std::string min_time;
1808 std::string min_warmup_time;
1809 std::string iterations;
1810 std::string repetitions;
1811 std::string time_type;
1812 std::string threads;
1816 std::string str()
const;
1824class BENCHMARK_EXPORT BenchmarkReporter {
1830 size_t name_field_width = 0;
1831 static const char* executable_name;
1835 struct BENCHMARK_EXPORT Run {
1836 static const int64_t no_repetition_index = -1;
1837 enum RunType { RT_Iteration, RT_Aggregate };
1840 : run_type(RT_Iteration),
1841 aggregate_unit(kTime),
1842 skipped(internal::NotSkipped),
1845 time_unit(GetDefaultTimeUnit()),
1846 real_accumulated_time(0),
1847 cpu_accumulated_time(0),
1848 max_heapbytes_used(0),
1849 use_real_time_for_initial_big_o(
false),
1851 complexity_lambda(),
1854 report_big_o(
false),
1856 allocs_per_iter(0.0) {}
1858 std::string benchmark_name()
const;
1860 int64_t family_index;
1861 int64_t per_family_instance_index;
1863 std::string aggregate_name;
1864 StatisticUnit aggregate_unit;
1865 std::string report_label;
1866 internal::Skipped skipped;
1867 std::string skip_message;
1869 IterationCount iterations;
1871 int64_t repetition_index;
1872 int64_t repetitions;
1874 double real_accumulated_time;
1875 double cpu_accumulated_time;
1881 double GetAdjustedRealTime()
const;
1887 double GetAdjustedCPUTime()
const;
1890 double max_heapbytes_used;
1894 bool use_real_time_for_initial_big_o;
1898 BigOFunc* complexity_lambda;
1899 ComplexityN complexity_n;
1902 const std::vector<internal::Statistics>* statistics;
1908 UserCounters counters;
1912 double allocs_per_iter;
1915 struct PerFamilyRunReports {
1916 PerFamilyRunReports() : num_runs_total(0), num_runs_done(0) {}
1925 std::vector<BenchmarkReporter::Run> Runs;
1930 BenchmarkReporter();
1938 virtual bool ReportContext(
const Context& context) = 0;
1942 virtual void ReportRunsConfig(
double ,
1953 virtual void ReportRuns(
const std::vector<Run>& report) = 0;
1957 virtual void Finalize() {}
1961 void SetOutputStream(std::ostream* out) {
1963 output_stream_ = out;
1968 void SetErrorStream(std::ostream* err) {
1970 error_stream_ = err;
1973 std::ostream& GetOutputStream()
const {
return *output_stream_; }
1975 std::ostream& GetErrorStream()
const {
return *error_stream_; }
1977 virtual ~BenchmarkReporter();
1982 static void PrintBasicContext(std::ostream* out, Context
const& context);
1985 std::ostream* output_stream_;
1986 std::ostream* error_stream_;
1991class BENCHMARK_EXPORT ConsoleReporter :
public BenchmarkReporter {
1993 enum OutputOptions {
1997 OO_ColorTabular = OO_Color | OO_Tabular,
1998 OO_Defaults = OO_ColorTabular
2000 explicit ConsoleReporter(OutputOptions opts_ = OO_Defaults)
2001 : output_options_(opts_), name_field_width_(0), printed_header_(
false) {}
2003 bool ReportContext(
const Context& context)
override;
2004 void ReportRuns(
const std::vector<Run>& reports)
override;
2007 virtual void PrintRunData(
const Run& result);
2008 virtual void PrintHeader(
const Run& run);
2010 OutputOptions output_options_;
2011 size_t name_field_width_;
2012 UserCounters prev_counters_;
2013 bool printed_header_;
2016class BENCHMARK_EXPORT JSONReporter :
public BenchmarkReporter {
2018 JSONReporter() : first_report_(
true) {}
2019 bool ReportContext(
const Context& context)
override;
2020 void ReportRuns(
const std::vector<Run>& reports)
override;
2021 void Finalize()
override;
2024 void PrintRunData(
const Run& run);
2029class BENCHMARK_EXPORT BENCHMARK_DEPRECATED_MSG(
2030 "The CSV Reporter will be removed in a future release") CSVReporter
2033 CSVReporter() : printed_header_(false) {}
2034 bool ReportContext(
const Context& context)
override;
2035 void ReportRuns(
const std::vector<Run>& reports)
override;
2038 void PrintRunData(
const Run& run);
2040 bool printed_header_;
2041 std::set<std::string> user_counter_names_;
2044inline const char* GetTimeUnitString(TimeUnit unit) {
2055 BENCHMARK_UNREACHABLE();
2058inline double GetTimeUnitMultiplier(TimeUnit unit) {
2069 BENCHMARK_UNREACHABLE();
2082std::vector<int64_t> CreateRange(int64_t lo, int64_t hi,
int multi);
2086std::vector<int64_t> CreateDenseRange(int64_t start, int64_t limit,
int step);
2090#if defined(_MSC_VER)
Definition benchmark.h:1824
Definition benchmark.h:1137
Definition benchmark.h:644
Definition benchmark.h:422
Definition benchmark.h:469
Definition benchmark.h:767
Definition benchmark_register.cc:73
Definition benchmark_api_internal.h:18
Definition perf_counters.h:149
Definition thread_manager.h:12
Definition thread_timer.h:10
Definition benchmark.h:1804
Definition benchmark.h:1826
Definition benchmark.h:1835
Definition benchmark.h:1766
Definition benchmark.h:1765
Definition benchmark.h:426
Definition benchmark.h:1075
Definition benchmark.h:1074
Definition benchmark.h:1789
Definition benchmark.h:1123