164#ifndef BENCHMARK_BENCHMARK_H_
165#define BENCHMARK_BENCHMARK_H_
174#include <initializer_list>
181#include <type_traits>
185#include "benchmark/export.h"
191#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \
192 TypeName(const TypeName&) = delete; \
193 TypeName& operator=(const TypeName&) = delete
195#ifdef BENCHMARK_HAS_CXX17
196#define BENCHMARK_UNUSED [[maybe_unused]]
197#elif defined(__GNUC__) || defined(__clang__)
198#define BENCHMARK_UNUSED __attribute__((unused))
200#define BENCHMARK_UNUSED
206#if defined(__clang__)
207#define BENCHMARK_DONT_OPTIMIZE __attribute__((optnone))
208#elif defined(__GNUC__) || defined(__GNUG__)
209#define BENCHMARK_DONT_OPTIMIZE __attribute__((optimize(0)))
212#define BENCHMARK_DONT_OPTIMIZE
215#if defined(__GNUC__) || defined(__clang__)
216#define BENCHMARK_ALWAYS_INLINE __attribute__((always_inline))
217#elif defined(_MSC_VER) && !defined(__clang__)
218#define BENCHMARK_ALWAYS_INLINE __forceinline
219#define __func__ __FUNCTION__
221#define BENCHMARK_ALWAYS_INLINE
224#define BENCHMARK_INTERNAL_TOSTRING2(x) #x
225#define BENCHMARK_INTERNAL_TOSTRING(x) BENCHMARK_INTERNAL_TOSTRING2(x)
228#if (defined(__GNUC__) && !defined(__NVCC__) && !defined(__NVCOMPILER)) || defined(__clang__)
229#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)
230#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
231#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
232 _Pragma("GCC diagnostic push") \
233 _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
234#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma("GCC diagnostic pop")
235#elif defined(__NVCOMPILER)
236#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)
237#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
238#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
239 _Pragma("diagnostic push") \
240 _Pragma("diag_suppress deprecated_entity_with_custom_message")
241#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma("diagnostic pop")
243#define BENCHMARK_BUILTIN_EXPECT(x, y) x
244#define BENCHMARK_DEPRECATED_MSG(msg)
245#define BENCHMARK_WARNING_MSG(msg) \
246 __pragma(message(__FILE__ "(" BENCHMARK_INTERNAL_TOSTRING( \
247 __LINE__) ") : warning note: " msg))
248#define BENCHMARK_DISABLE_DEPRECATED_WARNING
249#define BENCHMARK_RESTORE_DEPRECATED_WARNING
253#if defined(__GNUC__) && !defined(__clang__)
254#define BENCHMARK_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
258#define __has_builtin(x) 0
261#if defined(__GNUC__) || __has_builtin(__builtin_unreachable)
262#define BENCHMARK_UNREACHABLE() __builtin_unreachable()
263#elif defined(_MSC_VER)
264#define BENCHMARK_UNREACHABLE() __assume(false)
266#define BENCHMARK_UNREACHABLE() ((void)0)
271#if defined(__i386__) || defined(__x86_64__)
272#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
273#elif defined(__powerpc64__)
274#define BENCHMARK_INTERNAL_CACHELINE_SIZE 128
275#elif defined(__aarch64__)
276#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
277#elif defined(__arm__)
282#if defined(__ARM_ARCH_5T__)
283#define BENCHMARK_INTERNAL_CACHELINE_SIZE 32
284#elif defined(__ARM_ARCH_7A__)
285#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
290#ifndef BENCHMARK_INTERNAL_CACHELINE_SIZE
293#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
299#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED \
300 __attribute__((aligned(BENCHMARK_INTERNAL_CACHELINE_SIZE)))
301#elif defined(_MSC_VER)
302#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED \
303 __declspec(align(BENCHMARK_INTERNAL_CACHELINE_SIZE))
305#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED
311#pragma warning(disable : 4251)
317#if (__cplusplus < 201402L || (defined(_MSC_VER) && _MSVC_LANG < 201402L))
318template <
typename T,
typename... Args>
319std::unique_ptr<T> make_unique(Args&&... args) {
320 return std::unique_ptr<T>(
new T(std::forward<Args>(args)...));
323using ::std::make_unique;
327class BenchmarkReporter;
330using IterationCount = int64_t;
336const char kDefaultMinTimeStr[] =
"0.5s";
338BENCHMARK_EXPORT
void MaybeReenterWithoutASLR(
int,
char**);
341BENCHMARK_EXPORT std::string GetBenchmarkVersion();
343BENCHMARK_EXPORT
void PrintDefaultHelp();
345BENCHMARK_EXPORT
void Initialize(
int* argc,
char** argv,
346 void (*HelperPrintf)() = PrintDefaultHelp);
347BENCHMARK_EXPORT
void Shutdown();
351BENCHMARK_EXPORT
bool ReportUnrecognizedArguments(
int argc,
char** argv);
354BENCHMARK_EXPORT std::string GetBenchmarkFilter();
360BENCHMARK_EXPORT
void SetBenchmarkFilter(std::string value);
363BENCHMARK_EXPORT int32_t GetBenchmarkVerbosity();
368BENCHMARK_EXPORT BenchmarkReporter* CreateDefaultDisplayReporter();
386BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks();
387BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks(std::string spec);
389BENCHMARK_EXPORT
size_t
390RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter);
391BENCHMARK_EXPORT
size_t
392RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, std::string spec);
394BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks(
395 BenchmarkReporter* display_reporter, BenchmarkReporter* file_reporter);
396BENCHMARK_EXPORT
size_t
397RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
398 BenchmarkReporter* file_reporter, std::string spec);
402enum TimeUnit { kNanosecond, kMicrosecond, kMillisecond, kSecond };
404BENCHMARK_EXPORT TimeUnit GetDefaultTimeUnit();
408BENCHMARK_EXPORT
void SetDefaultTimeUnit(TimeUnit unit);
415 static constexpr int64_t TombstoneValue = std::numeric_limits<int64_t>::max();
421 total_allocated_bytes(TombstoneValue),
422 net_heap_growth(TombstoneValue),
423 memory_iterations(0) {}
429 int64_t max_bytes_used;
433 int64_t total_allocated_bytes;
438 int64_t net_heap_growth;
440 IterationCount memory_iterations;
446 virtual void Start() = 0;
449 virtual void Stop(Result& result) = 0;
455void RegisterMemoryManager(MemoryManager* memory_manager);
465 virtual void AfterSetupStart() = 0;
469 virtual void BeforeTeardownStop() = 0;
479void AddCustomContext(
const std::string& key,
const std::string& value);
484class BenchmarkFamilies;
486BENCHMARK_EXPORT std::map<std::string, std::string>*& GetGlobalContext();
489void UseCharPointer(
char const volatile*);
493BENCHMARK_EXPORT Benchmark* RegisterBenchmarkInternal(
494 std::unique_ptr<Benchmark>);
497BENCHMARK_EXPORT
int InitializeStreams();
498BENCHMARK_UNUSED
static int stream_init_anchor = InitializeStreams();
502#if (!defined(__GNUC__) && !defined(__clang__)) || defined(__pnacl__) || \
503 defined(__EMSCRIPTEN__)
504#define BENCHMARK_HAS_NO_INLINE_ASSEMBLY
509inline BENCHMARK_ALWAYS_INLINE
void ClobberMemory() {
510 std::atomic_signal_fence(std::memory_order_acq_rel);
517#ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY
518#if !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER)
520BENCHMARK_DEPRECATED_MSG(
521 "The const-ref version of this method can permit "
522 "undesired compiler optimizations in benchmarks")
523inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
524 asm volatile(
"" : :
"r,m"(value) :
"memory");
528inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp& value) {
529#if defined(__clang__)
530 asm volatile(
"" :
"+r,m"(value) : :
"memory");
532 asm volatile(
"" :
"+m,r"(value) : :
"memory");
537inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp&& value) {
538#if defined(__clang__)
539 asm volatile(
"" :
"+r,m"(value) : :
"memory");
541 asm volatile(
"" :
"+m,r"(value) : :
"memory");
549BENCHMARK_DEPRECATED_MSG(
550 "The const-ref version of this method can permit "
551 "undesired compiler optimizations in benchmarks")
552inline BENCHMARK_ALWAYS_INLINE
553 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
554 (sizeof(Tp) <= sizeof(Tp*))>::type
555 DoNotOptimize(Tp const& value) {
556 asm volatile(
"" : :
"r,m"(value) :
"memory");
560BENCHMARK_DEPRECATED_MSG(
561 "The const-ref version of this method can permit "
562 "undesired compiler optimizations in benchmarks")
563inline BENCHMARK_ALWAYS_INLINE
564 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
565 (sizeof(Tp) > sizeof(Tp*))>::type
566 DoNotOptimize(Tp const& value) {
567 asm volatile(
"" : :
"m"(value) :
"memory");
571inline BENCHMARK_ALWAYS_INLINE
572 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
573 (
sizeof(Tp) <=
sizeof(Tp*))>::type
574 DoNotOptimize(Tp& value) {
575 asm volatile(
"" :
"+m,r"(value) : :
"memory");
579inline BENCHMARK_ALWAYS_INLINE
580 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
581 (
sizeof(Tp) >
sizeof(Tp*))>::type
582 DoNotOptimize(Tp& value) {
583 asm volatile(
"" :
"+m"(value) : :
"memory");
587inline BENCHMARK_ALWAYS_INLINE
588 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
589 (
sizeof(Tp) <=
sizeof(Tp*))>::type
590 DoNotOptimize(Tp&& value) {
591 asm volatile(
"" :
"+m,r"(value) : :
"memory");
595inline BENCHMARK_ALWAYS_INLINE
596 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
597 (
sizeof(Tp) >
sizeof(Tp*))>::type
598 DoNotOptimize(Tp&& value) {
599 asm volatile(
"" :
"+m"(value) : :
"memory");
604#elif defined(_MSC_VER)
606BENCHMARK_DEPRECATED_MSG(
607 "The const-ref version of this method can permit "
608 "undesired compiler optimizations in benchmarks")
609inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
610 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
616inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp&& value) {
617 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
632 kAvgThreads = 1 << 1,
634 kAvgThreadsRate = kIsRate | kAvgThreads,
637 kIsIterationInvariant = 1 << 2,
641 kIsIterationInvariantRate = kIsRate | kIsIterationInvariant,
644 kAvgIterations = 1 << 3,
646 kAvgIterationsRate = kIsRate | kAvgIterations,
663 BENCHMARK_ALWAYS_INLINE
664 Counter(
double v = 0., Flags f = kDefaults, OneK k = kIs1000)
665 : value(v), flags(f), oneK(k) {}
667 BENCHMARK_ALWAYS_INLINE
operator double const&()
const {
return value; }
668 BENCHMARK_ALWAYS_INLINE
operator double&() {
return value; }
673Counter::Flags
inline operator|(
const Counter::Flags& LHS,
674 const Counter::Flags& RHS) {
675 return static_cast<Counter::Flags
>(
static_cast<int>(LHS) |
676 static_cast<int>(RHS));
680typedef std::map<std::string, Counter> UserCounters;
686enum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLambda };
688typedef int64_t ComplexityN;
690enum StatisticUnit { kTime, kPercentage };
694typedef double(BigOFunc)(ComplexityN);
698typedef double(StatisticsFunc)(
const std::vector<double>&);
703 StatisticsFunc* compute_;
706 Statistics(
const std::string& name, StatisticsFunc* compute,
707 StatisticUnit unit = kTime)
708 : name_(name), compute_(compute), unit_(unit) {}
716enum AggregationReportMode :
unsigned {
721 ARM_Default = 1U << 0U,
723 ARM_FileReportAggregatesOnly = 1U << 1U,
725 ARM_DisplayReportAggregatesOnly = 1U << 2U,
727 ARM_ReportAggregatesOnly =
728 ARM_FileReportAggregatesOnly | ARM_DisplayReportAggregatesOnly
731enum Skipped :
unsigned {
742#pragma warning(disable : 4324)
746class BENCHMARK_EXPORT BENCHMARK_INTERNAL_CACHELINE_ALIGNED
State {
764 inline bool KeepRunning();
776 inline bool KeepRunningBatch(IterationCount n);
825 void SkipWithMessage(
const std::string& msg);
846 void SkipWithError(
const std::string& msg);
849 bool skipped()
const {
return internal::NotSkipped != skipped_; }
852 bool error_occurred()
const {
return internal::SkippedWithError == skipped_; }
861 void SetIterationTime(
double seconds);
868 BENCHMARK_ALWAYS_INLINE
869 void SetBytesProcessed(int64_t bytes) {
870 counters[
"bytes_per_second"] =
871 Counter(
static_cast<double>(bytes), Counter::kIsRate, Counter::kIs1024);
874 BENCHMARK_ALWAYS_INLINE
875 int64_t bytes_processed()
const {
876 if (counters.find(
"bytes_per_second") != counters.end())
877 return static_cast<int64_t
>(counters.at(
"bytes_per_second"));
886 BENCHMARK_ALWAYS_INLINE
887 void SetComplexityN(ComplexityN complexity_n) {
888 complexity_n_ = complexity_n;
891 BENCHMARK_ALWAYS_INLINE
892 ComplexityN complexity_length_n()
const {
return complexity_n_; }
900 BENCHMARK_ALWAYS_INLINE
901 void SetItemsProcessed(int64_t items) {
902 counters[
"items_per_second"] =
903 Counter(
static_cast<double>(items), benchmark::Counter::kIsRate);
906 BENCHMARK_ALWAYS_INLINE
907 int64_t items_processed()
const {
908 if (counters.find(
"items_per_second") != counters.end())
909 return static_cast<int64_t
>(counters.at(
"items_per_second"));
925 void SetLabel(
const std::string& label);
928 BENCHMARK_ALWAYS_INLINE
929 int64_t range(std::size_t pos = 0)
const {
930 assert(range_.size() > pos);
934 BENCHMARK_DEPRECATED_MSG(
"use 'range(0)' instead")
935 int64_t range_x()
const {
return range(0); }
937 BENCHMARK_DEPRECATED_MSG(
"use 'range(1)' instead")
938 int64_t range_y()
const {
return range(1); }
941 BENCHMARK_ALWAYS_INLINE
942 int threads()
const {
return threads_; }
945 BENCHMARK_ALWAYS_INLINE
946 int thread_index()
const {
return thread_index_; }
948 BENCHMARK_ALWAYS_INLINE
949 IterationCount iterations()
const {
950 if (BENCHMARK_BUILTIN_EXPECT(!started_,
false)) {
953 return max_iterations - total_iterations_ + batch_leftover_;
956 BENCHMARK_ALWAYS_INLINE
957 std::string name()
const {
return name_; }
963 IterationCount total_iterations_;
968 IterationCount batch_leftover_;
971 const IterationCount max_iterations;
976 internal::Skipped skipped_;
979 std::vector<int64_t> range_;
981 ComplexityN complexity_n_;
985 UserCounters counters;
988 State(std::string name, IterationCount max_iters,
989 const std::vector<int64_t>& ranges,
int thread_i,
int n_threads,
994 void StartKeepRunning();
997 inline bool KeepRunningInternal(IterationCount n,
bool is_batch);
998 void FinishKeepRunning();
1000 const std::string name_;
1001 const int thread_index_;
1011#if defined(_MSC_VER)
1015inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunning() {
1016 return KeepRunningInternal(1,
false);
1019inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunningBatch(IterationCount n) {
1020 return KeepRunningInternal(n,
true);
1023inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunningInternal(IterationCount n,
1029 assert(is_batch || n == 1);
1030 if (BENCHMARK_BUILTIN_EXPECT(total_iterations_ >= n,
true)) {
1031 total_iterations_ -= n;
1036 if (!skipped() && total_iterations_ >= n) {
1037 total_iterations_ -= n;
1042 if (is_batch && total_iterations_ != 0) {
1043 batch_leftover_ = n - total_iterations_;
1044 total_iterations_ = 0;
1047 FinishKeepRunning();
1053 typedef std::forward_iterator_tag iterator_category;
1057 typedef std::ptrdiff_t difference_type;
1061 BENCHMARK_ALWAYS_INLINE
1064 BENCHMARK_ALWAYS_INLINE
1066 : cached_(st->skipped() ? 0 : st->max_iterations), parent_(st) {}
1069 BENCHMARK_ALWAYS_INLINE
1070 Value operator*()
const {
return Value(); }
1072 BENCHMARK_ALWAYS_INLINE
1073 StateIterator& operator++() {
1074 assert(cached_ > 0);
1079 BENCHMARK_ALWAYS_INLINE
1080 bool operator!=(StateIterator
const&)
const {
1081 if (BENCHMARK_BUILTIN_EXPECT(cached_ != 0,
true))
return true;
1082 parent_->FinishKeepRunning();
1087 IterationCount cached_;
1088 State*
const parent_;
1091inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::begin() {
1092 return StateIterator(
this);
1094inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::end() {
1096 return StateIterator();
1102 virtual void RunThreads(
const std::function<
void(
int)>& fn) = 0;
1108using threadrunner_factory =
1109 std::function<std::unique_ptr<ThreadRunnerBase>(
int)>;
1111typedef void(Function)(
State&);
1127 Benchmark* Name(
const std::string& name);
1140 Benchmark* Range(int64_t start, int64_t limit);
1145 Benchmark* DenseRange(int64_t start, int64_t limit,
int step = 1);
1150 Benchmark* Args(
const std::vector<int64_t>& args);
1155 Benchmark* ArgPair(int64_t x, int64_t y) {
1156 std::vector<int64_t> args;
1165 Benchmark* Ranges(
const std::vector<std::pair<int64_t, int64_t>>& ranges);
1170 Benchmark* ArgsProduct(
const std::vector<std::vector<int64_t>>& arglists);
1173 Benchmark* ArgName(
const std::string& name);
1177 Benchmark* ArgNames(
const std::vector<std::string>& names);
1182 Benchmark* RangePair(int64_t lo1, int64_t hi1, int64_t lo2, int64_t hi2) {
1183 std::vector<std::pair<int64_t, int64_t>> ranges;
1184 ranges.push_back(std::make_pair(lo1, hi1));
1185 ranges.push_back(std::make_pair(lo2, hi2));
1186 return Ranges(ranges);
1202 Benchmark* Setup(
const callback_function&);
1203 Benchmark* Teardown(callback_function&&);
1204 Benchmark* Teardown(
const callback_function&);
1213 Benchmark* RangeMultiplier(
int multiplier);
1233 Benchmark* Iterations(IterationCount n);
1244 Benchmark* ReportAggregatesOnly(
bool value =
true);
1247 Benchmark* DisplayAggregatesOnly(
bool value =
true);
1274 Benchmark* Complexity(BigO complexity = benchmark::oAuto);
1278 Benchmark* Complexity(BigOFunc* complexity);
1281 Benchmark* ComputeStatistics(
const std::string& name,
1282 StatisticsFunc* statistics,
1283 StatisticUnit unit = kTime);
1304 Benchmark* ThreadRange(
int min_threads,
int max_threads);
1310 Benchmark* DenseThreadRange(
int min_threads,
int max_threads,
int stride = 1);
1316 Benchmark* ThreadRunner(threadrunner_factory&& factory);
1318 virtual void Run(
State& state) = 0;
1320 TimeUnit GetTimeUnit()
const;
1323 explicit Benchmark(
const std::string& name);
1324 void SetName(
const std::string& name);
1327 const char* GetName()
const;
1328 int ArgsCnt()
const;
1329 const char* GetArgName(
int arg)
const;
1336 AggregationReportMode aggregation_report_mode_;
1337 std::vector<std::string> arg_names_;
1338 std::vector<std::vector<int64_t>> args_;
1340 TimeUnit time_unit_;
1341 bool use_default_time_unit_;
1343 int range_multiplier_;
1345 double min_warmup_time_;
1346 IterationCount iterations_;
1348 bool measure_process_cpu_time_;
1349 bool use_real_time_;
1350 bool use_manual_time_;
1352 BigOFunc* complexity_lambda_;
1353 std::vector<Statistics> statistics_;
1354 std::vector<int> thread_counts_;
1356 callback_function setup_;
1357 callback_function teardown_;
1359 threadrunner_factory threadrunner_;
1361 BENCHMARK_DISALLOW_COPY_AND_ASSIGN(
Benchmark);
1371 internal::Function* fn);
1373template <
class Lambda>
1378BENCHMARK_EXPORT
void ClearRegisteredBenchmarks();
1388 void Run(
State& st)
override;
1394template <
class Lambda>
1397 void Run(
State& st)
override { lambda_(st); }
1399 template <
class OLambda>
1401 :
Benchmark(name), lambda_(std::forward<OLambda>(lam)) {}
1410 internal::Function* fn) {
1411 return internal::RegisterBenchmarkInternal(
1412 ::benchmark::internal::make_unique<internal::FunctionBenchmark>(name,
1416template <
class Lambda>
1417internal::Benchmark* RegisterBenchmark(
const std::string& name, Lambda&& fn) {
1419 internal::LambdaBenchmark<typename std::decay<Lambda>::type>;
1420 return internal::RegisterBenchmarkInternal(
1421 ::benchmark::internal::make_unique<BenchType>(name,
1422 std::forward<Lambda>(fn)));
1425template <
class Lambda,
class... Args>
1426internal::Benchmark* RegisterBenchmark(
const std::string& name, Lambda&& fn,
1428 return benchmark::RegisterBenchmark(
1437 void Run(
State& st)
override {
1439 this->BenchmarkCase(st);
1444 virtual void SetUp(
const State&) {}
1445 virtual void TearDown(
const State&) {}
1447 virtual void SetUp(
State& st) { SetUp(
const_cast<const State&
>(st)); }
1448 virtual void TearDown(
State& st) { TearDown(
const_cast<const State&
>(st)); }
1451 virtual void BenchmarkCase(
State&) = 0;
1461#if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0)
1462#define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__
1464#define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__
1468#define BENCHMARK_PRIVATE_NAME(...) \
1469 BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, \
1472#define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c)
1473#define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c
1475#define BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method) \
1476 BaseClass##_##Method##_Benchmark
1478#define BENCHMARK_PRIVATE_DECLARE(n) \
1480 static ::benchmark::internal::Benchmark const* const BENCHMARK_PRIVATE_NAME( \
1483#define BENCHMARK(...) \
1484 BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
1485 (::benchmark::internal::RegisterBenchmarkInternal( \
1486 ::benchmark::internal::make_unique< \
1487 ::benchmark::internal::FunctionBenchmark>(#__VA_ARGS__, \
1491#define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a))
1492#define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->Args({(a1), (a2)})
1493#define BENCHMARK_WITH_UNIT(n, t) BENCHMARK(n)->Unit((t))
1494#define BENCHMARK_RANGE(n, lo, hi) BENCHMARK(n)->Range((lo), (hi))
1495#define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \
1496 BENCHMARK(n)->RangePair({{(l1), (h1)}, {(l2), (h2)}})
1509#define BENCHMARK_CAPTURE(func, test_case_name, ...) \
1510 BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
1511 (::benchmark::internal::RegisterBenchmarkInternal( \
1512 ::benchmark::internal::make_unique< \
1513 ::benchmark::internal::FunctionBenchmark>( \
1514 #func "/" #test_case_name, \
1515 [](::benchmark::State& st) { func(st, __VA_ARGS__); })))
1525#define BENCHMARK_TEMPLATE1(n, a) \
1526 BENCHMARK_PRIVATE_DECLARE(n) = \
1527 (::benchmark::internal::RegisterBenchmarkInternal( \
1528 ::benchmark::internal::make_unique< \
1529 ::benchmark::internal::FunctionBenchmark>(#n "<" #a ">", n<a>)))
1531#define BENCHMARK_TEMPLATE2(n, a, b) \
1532 BENCHMARK_PRIVATE_DECLARE(n) = \
1533 (::benchmark::internal::RegisterBenchmarkInternal( \
1534 ::benchmark::internal::make_unique< \
1535 ::benchmark::internal::FunctionBenchmark>(#n "<" #a "," #b ">", \
1538#define BENCHMARK_TEMPLATE(n, ...) \
1539 BENCHMARK_PRIVATE_DECLARE(n) = \
1540 (::benchmark::internal::RegisterBenchmarkInternal( \
1541 ::benchmark::internal::make_unique< \
1542 ::benchmark::internal::FunctionBenchmark>( \
1543 #n "<" #__VA_ARGS__ ">", n<__VA_ARGS__>)))
1557#define BENCHMARK_TEMPLATE1_CAPTURE(func, a, test_case_name, ...) \
1558 BENCHMARK_CAPTURE(func<a>, test_case_name, __VA_ARGS__)
1560#define BENCHMARK_TEMPLATE2_CAPTURE(func, a, b, test_case_name, ...) \
1561 BENCHMARK_PRIVATE_DECLARE(func) = \
1562 (::benchmark::internal::RegisterBenchmarkInternal( \
1563 ::benchmark::internal::make_unique< \
1564 ::benchmark::internal::FunctionBenchmark>( \
1565 #func "<" #a "," #b ">" \
1566 "/" #test_case_name, \
1567 [](::benchmark::State& st) { func<a, b>(st, __VA_ARGS__); })))
1569#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1570 class BaseClass##_##Method##_Benchmark : public BaseClass { \
1572 BaseClass##_##Method##_Benchmark() { \
1573 this->SetName(#BaseClass "/" #Method); \
1577 void BenchmarkCase(::benchmark::State&) override; \
1580#define BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1581 class BaseClass##_##Method##_Benchmark : public BaseClass<a> { \
1583 BaseClass##_##Method##_Benchmark() { \
1584 this->SetName(#BaseClass "<" #a ">/" #Method); \
1588 void BenchmarkCase(::benchmark::State&) override; \
1591#define BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1592 class BaseClass##_##Method##_Benchmark : public BaseClass<a, b> { \
1594 BaseClass##_##Method##_Benchmark() { \
1595 this->SetName(#BaseClass "<" #a "," #b ">/" #Method); \
1599 void BenchmarkCase(::benchmark::State&) override; \
1602#define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, ...) \
1603 class BaseClass##_##Method##_Benchmark : public BaseClass<__VA_ARGS__> { \
1605 BaseClass##_##Method##_Benchmark() { \
1606 this->SetName(#BaseClass "<" #__VA_ARGS__ ">/" #Method); \
1610 void BenchmarkCase(::benchmark::State&) override; \
1613#define BENCHMARK_DEFINE_F(BaseClass, Method) \
1614 BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1615 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1617#define BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a) \
1618 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1619 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1621#define BENCHMARK_TEMPLATE2_DEFINE_F(BaseClass, Method, a, b) \
1622 BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1623 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1625#define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, ...) \
1626 BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \
1627 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1629#define BENCHMARK_REGISTER_F(BaseClass, Method) \
1630 BENCHMARK_PRIVATE_REGISTER_F(BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method))
1632#define BENCHMARK_PRIVATE_REGISTER_F(TestName) \
1633 BENCHMARK_PRIVATE_DECLARE(TestName) = \
1634 (::benchmark::internal::RegisterBenchmarkInternal( \
1635 ::benchmark::internal::make_unique<TestName>()))
1637#define BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F(BaseClass, Method) \
1638 BaseClass##_##Method##_BenchmarkTemplate
1640#define BENCHMARK_TEMPLATE_METHOD_F(BaseClass, Method) \
1641 template <class... Args> \
1642 class BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F(BaseClass, Method) \
1643 : public BaseClass<Args...> { \
1645 using Base = BaseClass<Args...>; \
1646 void BenchmarkCase(::benchmark::State&) override; \
1648 template <class... Args> \
1649 void BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F( \
1650 BaseClass, Method)<Args...>::BenchmarkCase
1652#define BENCHMARK_TEMPLATE_PRIVATE_INSTANTIATE_F(BaseClass, Method, \
1654 class UniqueName : public BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F( \
1655 BaseClass, Method)<__VA_ARGS__> { \
1657 UniqueName() { this->SetName(#BaseClass "<" #__VA_ARGS__ ">/" #Method); } \
1659 BENCHMARK_PRIVATE_DECLARE(BaseClass##_##Method##_Benchmark) = \
1660 (::benchmark::internal::RegisterBenchmarkInternal( \
1661 ::benchmark::internal::make_unique<UniqueName>()))
1663#define BENCHMARK_TEMPLATE_INSTANTIATE_F(BaseClass, Method, ...) \
1664 BENCHMARK_TEMPLATE_PRIVATE_INSTANTIATE_F( \
1665 BaseClass, Method, BENCHMARK_PRIVATE_NAME(BaseClass##Method), \
1669#define BENCHMARK_F(BaseClass, Method) \
1670 BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1671 BENCHMARK_REGISTER_F(BaseClass, Method); \
1672 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1674#define BENCHMARK_TEMPLATE1_F(BaseClass, Method, a) \
1675 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1676 BENCHMARK_REGISTER_F(BaseClass, Method); \
1677 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1679#define BENCHMARK_TEMPLATE2_F(BaseClass, Method, a, b) \
1680 BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1681 BENCHMARK_REGISTER_F(BaseClass, Method); \
1682 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1684#define BENCHMARK_TEMPLATE_F(BaseClass, Method, ...) \
1685 BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \
1686 BENCHMARK_REGISTER_F(BaseClass, Method); \
1687 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1691#define BENCHMARK_MAIN() \
1692 int main(int argc, char** argv) { \
1693 benchmark::MaybeReenterWithoutASLR(argc, argv); \
1694 char arg0_default[] = "benchmark"; \
1695 char* args_default = reinterpret_cast<char*>(arg0_default); \
1698 argv = &args_default; \
1700 ::benchmark::Initialize(&argc, argv); \
1701 if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; \
1702 ::benchmark::RunSpecifiedBenchmarks(); \
1703 ::benchmark::Shutdown(); \
1706 int main(int, char**)
1711namespace benchmark {
1721 enum Scaling { UNKNOWN, ENABLED, DISABLED };
1725 double cycles_per_second;
1726 std::vector<CacheInfo> caches;
1727 std::vector<double> load_avg;
1733 BENCHMARK_DISALLOW_COPY_AND_ASSIGN(
CPUInfo);
1738 enum class ASLR { UNKNOWN, ENABLED, DISABLED };
1746 BENCHMARK_DISALLOW_COPY_AND_ASSIGN(
SystemInfo);
1753 std::string function_name;
1755 std::string min_time;
1756 std::string min_warmup_time;
1757 std::string iterations;
1758 std::string repetitions;
1759 std::string time_type;
1760 std::string threads;
1764 std::string str()
const;
1778 size_t name_field_width = 0;
1779 static const char* executable_name;
1784 static const int64_t no_repetition_index = -1;
1785 enum RunType { RT_Iteration, RT_Aggregate };
1788 : run_type(RT_Iteration),
1789 aggregate_unit(kTime),
1790 skipped(internal::NotSkipped),
1793 time_unit(GetDefaultTimeUnit()),
1794 real_accumulated_time(0),
1795 cpu_accumulated_time(0),
1796 max_heapbytes_used(0),
1797 use_real_time_for_initial_big_o(
false),
1799 complexity_lambda(),
1801 report_big_o(
false),
1803 allocs_per_iter(0.0) {}
1805 std::string benchmark_name()
const;
1807 int64_t family_index;
1808 int64_t per_family_instance_index;
1810 std::string aggregate_name;
1811 StatisticUnit aggregate_unit;
1812 std::string report_label;
1813 internal::Skipped skipped;
1814 std::string skip_message;
1816 IterationCount iterations;
1818 int64_t repetition_index;
1819 int64_t repetitions;
1821 double real_accumulated_time;
1822 double cpu_accumulated_time;
1828 double GetAdjustedRealTime()
const;
1834 double GetAdjustedCPUTime()
const;
1837 double max_heapbytes_used;
1841 bool use_real_time_for_initial_big_o;
1845 BigOFunc* complexity_lambda;
1846 ComplexityN complexity_n;
1849 const std::vector<internal::Statistics>* statistics;
1855 UserCounters counters;
1859 double allocs_per_iter;
1872 std::vector<BenchmarkReporter::Run> Runs;
1885 virtual bool ReportContext(
const Context& context) = 0;
1889 virtual void ReportRunsConfig(
double ,
1900 virtual void ReportRuns(
const std::vector<Run>& report) = 0;
1904 virtual void Finalize() {}
1908 void SetOutputStream(std::ostream* out) {
1910 output_stream_ = out;
1915 void SetErrorStream(std::ostream* err) {
1917 error_stream_ = err;
1920 std::ostream& GetOutputStream()
const {
return *output_stream_; }
1922 std::ostream& GetErrorStream()
const {
return *error_stream_; }
1924 virtual ~BenchmarkReporter();
1929 static void PrintBasicContext(std::ostream* out, Context
const& context);
1932 std::ostream* output_stream_;
1933 std::ostream* error_stream_;
1940 enum OutputOptions {
1944 OO_ColorTabular = OO_Color | OO_Tabular,
1945 OO_Defaults = OO_ColorTabular
1948 : output_options_(opts_), name_field_width_(0), printed_header_(
false) {}
1950 bool ReportContext(
const Context& context)
override;
1951 void ReportRuns(
const std::vector<Run>& reports)
override;
1954 virtual void PrintRunData(
const Run& result);
1955 virtual void PrintHeader(
const Run& run);
1957 OutputOptions output_options_;
1958 size_t name_field_width_;
1959 UserCounters prev_counters_;
1960 bool printed_header_;
1966 bool ReportContext(
const Context& context)
override;
1967 void ReportRuns(
const std::vector<Run>& reports)
override;
1968 void Finalize()
override;
1971 void PrintRunData(
const Run& run);
1976class BENCHMARK_EXPORT BENCHMARK_DEPRECATED_MSG(
1977 "The CSV Reporter will be removed in a future release") CSVReporter
1980 CSVReporter() : printed_header_(false) {}
1981 bool ReportContext(
const Context& context)
override;
1982 void ReportRuns(
const std::vector<Run>& reports)
override;
1985 void PrintRunData(
const Run& run);
1987 bool printed_header_;
1988 std::set<std::string> user_counter_names_;
1991inline const char* GetTimeUnitString(TimeUnit unit) {
2002 BENCHMARK_UNREACHABLE();
2005inline double GetTimeUnitMultiplier(TimeUnit unit) {
2016 BENCHMARK_UNREACHABLE();
2029std::vector<int64_t> CreateRange(int64_t lo, int64_t hi,
int multi);
2033std::vector<int64_t> CreateDenseRange(int64_t start, int64_t limit,
int step);
2037#if defined(_MSC_VER)
Definition benchmark.h:1772
Definition benchmark.h:1938
Definition benchmark.h:623
Definition benchmark.h:1433
Definition benchmark.h:1963
Definition benchmark.h:413
Definition benchmark.h:460
Definition benchmark.h:746
Definition benchmark_register.cc:73
Definition benchmark_api_internal.h:18
Definition benchmark.h:1119
Definition benchmark.h:1383
Definition benchmark.h:1395
Definition perf_counters.h:149
Definition thread_manager.h:12
Definition thread_timer.h:10
Definition benchmark.h:1752
Definition benchmark.h:1774
Definition benchmark.h:1862
Definition benchmark.h:1783
Definition benchmark.h:1714
Definition benchmark.h:1713
Definition benchmark.h:417
Definition benchmark.h:1052
Definition benchmark.h:1051
Definition benchmark.h:1737
Definition benchmark.h:1100
Definition benchmark.h:701