163#ifndef BENCHMARK_BENCHMARK_H_
164#define BENCHMARK_BENCHMARK_H_
167#if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
168#define BENCHMARK_HAS_CXX11
172#if __cplusplus >= 201703L || \
173 (defined(_MSC_VER) && _MSC_VER >= 1911 && _MSVC_LANG >= 201703L)
174#define BENCHMARK_HAS_CXX17
190#include "benchmark/export.h"
192#if defined(BENCHMARK_HAS_CXX11)
194#include <initializer_list>
195#include <type_traits>
203#ifndef BENCHMARK_HAS_CXX11
204#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \
205 TypeName(const TypeName&); \
206 TypeName& operator=(const TypeName&)
208#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \
209 TypeName(const TypeName&) = delete; \
210 TypeName& operator=(const TypeName&) = delete
213#ifdef BENCHMARK_HAS_CXX17
214#define BENCHMARK_UNUSED [[maybe_unused]]
215#elif defined(__GNUC__) || defined(__clang__)
216#define BENCHMARK_UNUSED __attribute__((unused))
218#define BENCHMARK_UNUSED
224#if defined(__clang__)
225#define BENCHMARK_DONT_OPTIMIZE __attribute__((optnone))
226#elif defined(__GNUC__) || defined(__GNUG__)
227#define BENCHMARK_DONT_OPTIMIZE __attribute__((optimize(0)))
230#define BENCHMARK_DONT_OPTIMIZE
233#if defined(__GNUC__) || defined(__clang__)
234#define BENCHMARK_ALWAYS_INLINE __attribute__((always_inline))
235#elif defined(_MSC_VER) && !defined(__clang__)
236#define BENCHMARK_ALWAYS_INLINE __forceinline
237#define __func__ __FUNCTION__
239#define BENCHMARK_ALWAYS_INLINE
242#define BENCHMARK_INTERNAL_TOSTRING2(x) #x
243#define BENCHMARK_INTERNAL_TOSTRING(x) BENCHMARK_INTERNAL_TOSTRING2(x)
246#if (defined(__GNUC__) && !defined(__NVCC__) && !defined(__NVCOMPILER)) || defined(__clang__)
247#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)
248#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
249#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
250 _Pragma("GCC diagnostic push") \
251 _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
252#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma("GCC diagnostic pop")
253#elif defined(__NVCOMPILER)
254#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)
255#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
256#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
257 _Pragma("diagnostic push") \
258 _Pragma("diag_suppress deprecated_entity_with_custom_message")
259#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma("diagnostic pop")
261#define BENCHMARK_BUILTIN_EXPECT(x, y) x
262#define BENCHMARK_DEPRECATED_MSG(msg)
263#define BENCHMARK_WARNING_MSG(msg) \
264 __pragma(message(__FILE__ "(" BENCHMARK_INTERNAL_TOSTRING( \
265 __LINE__) ") : warning note: " msg))
266#define BENCHMARK_DISABLE_DEPRECATED_WARNING
267#define BENCHMARK_RESTORE_DEPRECATED_WARNING
271#if defined(__GNUC__) && !defined(__clang__)
272#define BENCHMARK_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
276#define __has_builtin(x) 0
279#if defined(__GNUC__) || __has_builtin(__builtin_unreachable)
280#define BENCHMARK_UNREACHABLE() __builtin_unreachable()
281#elif defined(_MSC_VER)
282#define BENCHMARK_UNREACHABLE() __assume(false)
284#define BENCHMARK_UNREACHABLE() ((void)0)
287#ifdef BENCHMARK_HAS_CXX11
288#define BENCHMARK_OVERRIDE override
290#define BENCHMARK_OVERRIDE
296#pragma warning(disable : 4251)
300class BenchmarkReporter;
303const char kDefaultMinTimeStr[] =
"0.5s";
305BENCHMARK_EXPORT
void PrintDefaultHelp();
307BENCHMARK_EXPORT
void Initialize(
int* argc,
char** argv,
308 void (*HelperPrinterf)() = PrintDefaultHelp);
309BENCHMARK_EXPORT
void Shutdown();
313BENCHMARK_EXPORT
bool ReportUnrecognizedArguments(
int argc,
char** argv);
316BENCHMARK_EXPORT std::string GetBenchmarkFilter();
322BENCHMARK_EXPORT
void SetBenchmarkFilter(std::string value);
325BENCHMARK_EXPORT int32_t GetBenchmarkVerbosity();
330BENCHMARK_EXPORT BenchmarkReporter* CreateDefaultDisplayReporter();
348BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks();
349BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks(std::string spec);
351BENCHMARK_EXPORT
size_t
352RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter);
353BENCHMARK_EXPORT
size_t
354RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, std::string spec);
356BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks(
357 BenchmarkReporter* display_reporter, BenchmarkReporter* file_reporter);
358BENCHMARK_EXPORT
size_t
359RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
360 BenchmarkReporter* file_reporter, std::string spec);
364enum TimeUnit { kNanosecond, kMicrosecond, kMillisecond, kSecond };
366BENCHMARK_EXPORT TimeUnit GetDefaultTimeUnit();
370BENCHMARK_EXPORT
void SetDefaultTimeUnit(TimeUnit unit);
377 static const int64_t TombstoneValue;
383 total_allocated_bytes(TombstoneValue),
384 net_heap_growth(TombstoneValue) {}
390 int64_t max_bytes_used;
394 int64_t total_allocated_bytes;
399 int64_t net_heap_growth;
405 virtual void Start() = 0;
408 virtual void Stop(Result& result) = 0;
414void RegisterMemoryManager(MemoryManager* memory_manager);
418void AddCustomContext(
const std::string& key,
const std::string& value);
423class BenchmarkFamilies;
425BENCHMARK_EXPORT std::map<std::string, std::string>*& GetGlobalContext();
428void UseCharPointer(
char const volatile*);
432BENCHMARK_EXPORT Benchmark* RegisterBenchmarkInternal(Benchmark*);
435BENCHMARK_EXPORT
int InitializeStreams();
436BENCHMARK_UNUSED
static int stream_init_anchor = InitializeStreams();
440#if (!defined(__GNUC__) && !defined(__clang__)) || defined(__pnacl__) || \
441 defined(__EMSCRIPTEN__)
442#define BENCHMARK_HAS_NO_INLINE_ASSEMBLY
447#ifdef BENCHMARK_HAS_CXX11
448inline BENCHMARK_ALWAYS_INLINE
void ClobberMemory() {
449 std::atomic_signal_fence(std::memory_order_acq_rel);
457#ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY
458#if !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER)
460BENCHMARK_DEPRECATED_MSG(
461 "The const-ref version of this method can permit "
462 "undesired compiler optimizations in benchmarks")
463inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
464 asm volatile(
"" : :
"r,m"(value) :
"memory");
468inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp& value) {
469#if defined(__clang__)
470 asm volatile(
"" :
"+r,m"(value) : :
"memory");
472 asm volatile(
"" :
"+m,r"(value) : :
"memory");
476#ifdef BENCHMARK_HAS_CXX11
478inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp&& value) {
479#if defined(__clang__)
480 asm volatile(
"" :
"+r,m"(value) : :
"memory");
482 asm volatile(
"" :
"+m,r"(value) : :
"memory");
486#elif defined(BENCHMARK_HAS_CXX11) && (__GNUC__ >= 5)
490BENCHMARK_DEPRECATED_MSG(
491 "The const-ref version of this method can permit "
492 "undesired compiler optimizations in benchmarks")
493inline BENCHMARK_ALWAYS_INLINE
494 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
495 (sizeof(Tp) <= sizeof(Tp*))>::type
496 DoNotOptimize(Tp const& value) {
497 asm volatile(
"" : :
"r,m"(value) :
"memory");
501BENCHMARK_DEPRECATED_MSG(
502 "The const-ref version of this method can permit "
503 "undesired compiler optimizations in benchmarks")
504inline BENCHMARK_ALWAYS_INLINE
505 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
506 (sizeof(Tp) > sizeof(Tp*))>::type
507 DoNotOptimize(Tp const& value) {
508 asm volatile(
"" : :
"m"(value) :
"memory");
512inline BENCHMARK_ALWAYS_INLINE
513 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
514 (
sizeof(Tp) <=
sizeof(Tp*))>::type
515 DoNotOptimize(Tp& value) {
516 asm volatile(
"" :
"+m,r"(value) : :
"memory");
520inline BENCHMARK_ALWAYS_INLINE
521 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
522 (
sizeof(Tp) >
sizeof(Tp*))>::type
523 DoNotOptimize(Tp& value) {
524 asm volatile(
"" :
"+m"(value) : :
"memory");
528inline BENCHMARK_ALWAYS_INLINE
529 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
530 (
sizeof(Tp) <=
sizeof(Tp*))>::type
531 DoNotOptimize(Tp&& value) {
532 asm volatile(
"" :
"+m,r"(value) : :
"memory");
536inline BENCHMARK_ALWAYS_INLINE
537 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
538 (
sizeof(Tp) >
sizeof(Tp*))>::type
539 DoNotOptimize(Tp&& value) {
540 asm volatile(
"" :
"+m"(value) : :
"memory");
548BENCHMARK_DEPRECATED_MSG(
549 "The const-ref version of this method can permit "
550 "undesired compiler optimizations in benchmarks")
551inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
552 asm volatile(
"" : :
"m"(value) :
"memory");
556inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp& value) {
557 asm volatile(
"" :
"+m"(value) : :
"memory");
560#ifdef BENCHMARK_HAS_CXX11
562inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp&& value) {
563 asm volatile(
"" :
"+m"(value) : :
"memory");
568#ifndef BENCHMARK_HAS_CXX11
569inline BENCHMARK_ALWAYS_INLINE
void ClobberMemory() {
570 asm volatile(
"" : : :
"memory");
573#elif defined(_MSC_VER)
575BENCHMARK_DEPRECATED_MSG(
576 "The const-ref version of this method can permit "
577 "undesired compiler optimizations in benchmarks")
578inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
579 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
583#ifndef BENCHMARK_HAS_CXX11
584inline BENCHMARK_ALWAYS_INLINE
void ClobberMemory() { _ReadWriteBarrier(); }
588BENCHMARK_DEPRECATED_MSG(
589 "The const-ref version of this method can permit "
590 "undesired compiler optimizations in benchmarks")
591inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
592 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
607 kAvgThreads = 1 << 1,
609 kAvgThreadsRate = kIsRate | kAvgThreads,
612 kIsIterationInvariant = 1 << 2,
616 kIsIterationInvariantRate = kIsRate | kIsIterationInvariant,
619 kAvgIterations = 1 << 3,
621 kAvgIterationsRate = kIsRate | kAvgIterations,
638 BENCHMARK_ALWAYS_INLINE
639 Counter(
double v = 0., Flags f = kDefaults, OneK k = kIs1000)
640 : value(v), flags(f), oneK(k) {}
642 BENCHMARK_ALWAYS_INLINE
operator double const &()
const {
return value; }
643 BENCHMARK_ALWAYS_INLINE
operator double&() {
return value; }
648Counter::Flags
inline operator|(
const Counter::Flags& LHS,
649 const Counter::Flags& RHS) {
650 return static_cast<Counter::Flags
>(
static_cast<int>(LHS) |
651 static_cast<int>(RHS));
655typedef std::map<std::string, Counter> UserCounters;
661enum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLambda };
663typedef int64_t IterationCount;
665enum StatisticUnit { kTime, kPercentage };
669typedef double(BigOFunc)(IterationCount);
673typedef double(StatisticsFunc)(
const std::vector<double>&);
678 StatisticsFunc* compute_;
681 Statistics(
const std::string& name, StatisticsFunc* compute,
682 StatisticUnit unit = kTime)
683 : name_(name), compute_(compute), unit_(unit) {}
691enum AggregationReportMode
692#if defined(BENCHMARK_HAS_CXX11)
701 ARM_Default = 1U << 0U,
703 ARM_FileReportAggregatesOnly = 1U << 1U,
705 ARM_DisplayReportAggregatesOnly = 1U << 2U,
707 ARM_ReportAggregatesOnly =
708 ARM_FileReportAggregatesOnly | ARM_DisplayReportAggregatesOnly
712#if defined(BENCHMARK_HAS_CXX11)
755 bool KeepRunningBatch(IterationCount n);
804 void SkipWithMessage(
const std::string& msg);
825 void SkipWithError(
const std::string& msg);
828 bool skipped()
const {
return internal::NotSkipped != skipped_; }
831 bool error_occurred()
const {
return internal::SkippedWithError == skipped_; }
840 void SetIterationTime(
double seconds);
847 BENCHMARK_ALWAYS_INLINE
848 void SetBytesProcessed(int64_t bytes) {
849 counters[
"bytes_per_second"] =
850 Counter(
static_cast<double>(bytes), Counter::kIsRate, Counter::kIs1024);
853 BENCHMARK_ALWAYS_INLINE
854 int64_t bytes_processed()
const {
855 if (counters.find(
"bytes_per_second") != counters.end())
856 return static_cast<int64_t
>(counters.at(
"bytes_per_second"));
865 BENCHMARK_ALWAYS_INLINE
866 void SetComplexityN(int64_t complexity_n) { complexity_n_ = complexity_n; }
868 BENCHMARK_ALWAYS_INLINE
869 int64_t complexity_length_n()
const {
return complexity_n_; }
877 BENCHMARK_ALWAYS_INLINE
878 void SetItemsProcessed(int64_t items) {
879 counters[
"items_per_second"] =
880 Counter(
static_cast<double>(items), benchmark::Counter::kIsRate);
883 BENCHMARK_ALWAYS_INLINE
884 int64_t items_processed()
const {
885 if (counters.find(
"items_per_second") != counters.end())
886 return static_cast<int64_t
>(counters.at(
"items_per_second"));
902 void SetLabel(
const std::string& label);
905 BENCHMARK_ALWAYS_INLINE
906 int64_t range(std::size_t pos = 0)
const {
907 assert(range_.size() > pos);
911 BENCHMARK_DEPRECATED_MSG(
"use 'range(0)' instead")
912 int64_t range_x()
const {
return range(0); }
914 BENCHMARK_DEPRECATED_MSG(
"use 'range(1)' instead")
915 int64_t range_y()
const {
return range(1); }
918 BENCHMARK_ALWAYS_INLINE
919 int threads()
const {
return threads_; }
922 BENCHMARK_ALWAYS_INLINE
923 int thread_index()
const {
return thread_index_; }
925 BENCHMARK_ALWAYS_INLINE
926 IterationCount iterations()
const {
927 if (BENCHMARK_BUILTIN_EXPECT(!started_,
false)) {
930 return max_iterations - total_iterations_ + batch_leftover_;
933 BENCHMARK_ALWAYS_INLINE
934 std::string name()
const {
return name_; }
940 IterationCount total_iterations_;
945 IterationCount batch_leftover_;
948 const IterationCount max_iterations;
953 internal::Skipped skipped_;
956 std::vector<int64_t> range_;
958 int64_t complexity_n_;
962 UserCounters counters;
965 State(std::string name, IterationCount max_iters,
966 const std::vector<int64_t>& ranges,
int thread_i,
int n_threads,
970 void StartKeepRunning();
973 bool KeepRunningInternal(IterationCount n,
bool is_batch);
974 void FinishKeepRunning();
976 const std::string name_;
977 const int thread_index_;
987inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunning() {
988 return KeepRunningInternal(1,
false);
991inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunningBatch(IterationCount n) {
992 return KeepRunningInternal(n,
true);
995inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunningInternal(IterationCount n,
1001 assert(is_batch || n == 1);
1002 if (BENCHMARK_BUILTIN_EXPECT(total_iterations_ >= n,
true)) {
1003 total_iterations_ -= n;
1008 if (!skipped() && total_iterations_ >= n) {
1009 total_iterations_ -= n;
1014 if (is_batch && total_iterations_ != 0) {
1015 batch_leftover_ = n - total_iterations_;
1016 total_iterations_ = 0;
1019 FinishKeepRunning();
1025 typedef std::forward_iterator_tag iterator_category;
1029 typedef std::ptrdiff_t difference_type;
1033 BENCHMARK_ALWAYS_INLINE
1036 BENCHMARK_ALWAYS_INLINE
1038 : cached_(st->skipped() ? 0 : st->max_iterations), parent_(st) {}
1041 BENCHMARK_ALWAYS_INLINE
1042 Value operator*()
const {
return Value(); }
1044 BENCHMARK_ALWAYS_INLINE
1045 StateIterator& operator++() {
1046 assert(cached_ > 0);
1051 BENCHMARK_ALWAYS_INLINE
1052 bool operator!=(StateIterator
const&)
const {
1053 if (BENCHMARK_BUILTIN_EXPECT(cached_ != 0,
true))
return true;
1054 parent_->FinishKeepRunning();
1059 IterationCount cached_;
1060 State*
const parent_;
1063inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::begin() {
1064 return StateIterator(
this);
1066inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::end() {
1068 return StateIterator();
1073typedef void(Function)(State&);
1081class BENCHMARK_EXPORT Benchmark {
1083 virtual ~Benchmark();
1089 Benchmark* Name(
const std::string& name);
1094 Benchmark* Arg(int64_t x);
1097 Benchmark* Unit(TimeUnit unit);
1102 Benchmark* Range(int64_t start, int64_t limit);
1107 Benchmark* DenseRange(int64_t start, int64_t limit,
int step = 1);
1112 Benchmark* Args(
const std::vector<int64_t>& args);
1117 Benchmark* ArgPair(int64_t x, int64_t y) {
1118 std::vector<int64_t> args;
1127 Benchmark* Ranges(
const std::vector<std::pair<int64_t, int64_t> >& ranges);
1132 Benchmark* ArgsProduct(
const std::vector<std::vector<int64_t> >& arglists);
1135 Benchmark* ArgName(
const std::string& name);
1139 Benchmark* ArgNames(
const std::vector<std::string>& names);
1144 Benchmark* RangePair(int64_t lo1, int64_t hi1, int64_t lo2, int64_t hi2) {
1145 std::vector<std::pair<int64_t, int64_t> > ranges;
1146 ranges.push_back(std::make_pair(lo1, hi1));
1147 ranges.push_back(std::make_pair(lo2, hi2));
1148 return Ranges(ranges);
1171 Benchmark* Apply(
void (*func)(Benchmark* benchmark));
1175 Benchmark* RangeMultiplier(
int multiplier);
1180 Benchmark* MinTime(
double t);
1186 Benchmark* MinWarmUpTime(
double t);
1195 Benchmark* Iterations(IterationCount n);
1200 Benchmark* Repetitions(
int n);
1206 Benchmark* ReportAggregatesOnly(
bool value =
true);
1209 Benchmark* DisplayAggregatesOnly(
bool value =
true);
1215 Benchmark* MeasureProcessCPUTime();
1223 Benchmark* UseRealTime();
1232 Benchmark* UseManualTime();
1236 Benchmark* Complexity(BigO complexity = benchmark::oAuto);
1240 Benchmark* Complexity(BigOFunc* complexity);
1243 Benchmark* ComputeStatistics(
const std::string& name,
1244 StatisticsFunc* statistics,
1245 StatisticUnit unit = kTime);
1252 Benchmark* Threads(
int t);
1266 Benchmark* ThreadRange(
int min_threads,
int max_threads);
1272 Benchmark* DenseThreadRange(
int min_threads,
int max_threads,
int stride = 1);
1275 Benchmark* ThreadPerCpu();
1277 virtual void Run(State& state) = 0;
1279 TimeUnit GetTimeUnit()
const;
1282 explicit Benchmark(
const std::string& name);
1283 void SetName(
const std::string& name);
1286 const char* GetName()
const;
1287 int ArgsCnt()
const;
1288 const char* GetArgName(
int arg)
const;
1291 friend class BenchmarkFamilies;
1292 friend class BenchmarkInstance;
1295 AggregationReportMode aggregation_report_mode_;
1296 std::vector<std::string> arg_names_;
1297 std::vector<std::vector<int64_t> > args_;
1299 TimeUnit time_unit_;
1300 bool use_default_time_unit_;
1302 int range_multiplier_;
1304 double min_warmup_time_;
1305 IterationCount iterations_;
1307 bool measure_process_cpu_time_;
1308 bool use_real_time_;
1309 bool use_manual_time_;
1311 BigOFunc* complexity_lambda_;
1312 std::vector<Statistics> statistics_;
1313 std::vector<int> thread_counts_;
1316 callback_function setup_;
1317 callback_function teardown_;
1319 Benchmark(Benchmark
const&)
1320#if defined(BENCHMARK_HAS_CXX11)
1325 Benchmark& operator=(Benchmark
const&)
1326#if defined(BENCHMARK_HAS_CXX11)
1338internal::Benchmark* RegisterBenchmark(
const std::string& name,
1339 internal::Function* fn);
1341#if defined(BENCHMARK_HAS_CXX11)
1342template <
class Lambda>
1343internal::Benchmark* RegisterBenchmark(
const std::string& name, Lambda&& fn);
1348BENCHMARK_EXPORT
void ClearRegisteredBenchmarks();
1353class BENCHMARK_EXPORT FunctionBenchmark :
public Benchmark {
1355 FunctionBenchmark(
const std::string& name, Function* func)
1356 : Benchmark(name), func_(func) {}
1358 void Run(State& st) BENCHMARK_OVERRIDE;
1364#ifdef BENCHMARK_HAS_CXX11
1365template <
class Lambda>
1366class LambdaBenchmark :
public Benchmark {
1368 void Run(State& st) BENCHMARK_OVERRIDE { lambda_(st); }
1371 template <
class OLambda>
1372 LambdaBenchmark(
const std::string& name, OLambda&& lam)
1373 : Benchmark(name), lambda_(std::forward<OLambda>(lam)) {}
1375 LambdaBenchmark(LambdaBenchmark
const&) =
delete;
1377 template <
class Lam>
1378 friend Benchmark* ::benchmark::RegisterBenchmark(
const std::string&, Lam&&);
1385inline internal::Benchmark* RegisterBenchmark(
const std::string& name,
1386 internal::Function* fn) {
1389 return internal::RegisterBenchmarkInternal(
1390 ::new internal::FunctionBenchmark(name, fn));
1393#ifdef BENCHMARK_HAS_CXX11
1394template <
class Lambda>
1395internal::Benchmark* RegisterBenchmark(
const std::string& name, Lambda&& fn) {
1397 internal::LambdaBenchmark<typename std::decay<Lambda>::type>;
1400 return internal::RegisterBenchmarkInternal(
1401 ::new BenchType(name, std::forward<Lambda>(fn)));
1405#if defined(BENCHMARK_HAS_CXX11) && \
1406 (!defined(BENCHMARK_GCC_VERSION) || BENCHMARK_GCC_VERSION >= 409)
1407template <
class Lambda,
class... Args>
1408internal::Benchmark* RegisterBenchmark(
const std::string& name, Lambda&& fn,
1410 return benchmark::RegisterBenchmark(
1414#define BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK
1420 Fixture() : internal::Benchmark(
"") {}
1422 void Run(
State& st) BENCHMARK_OVERRIDE {
1424 this->BenchmarkCase(st);
1429 virtual void SetUp(
const State&) {}
1430 virtual void TearDown(
const State&) {}
1432 virtual void SetUp(
State& st) { SetUp(
const_cast<const State&
>(st)); }
1433 virtual void TearDown(
State& st) { TearDown(
const_cast<const State&
>(st)); }
1436 virtual void BenchmarkCase(
State&) = 0;
1446#if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0)
1447#define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__
1449#define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__
1453#ifdef BENCHMARK_HAS_CXX11
1454#define BENCHMARK_PRIVATE_NAME(...) \
1455 BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, \
1458#define BENCHMARK_PRIVATE_NAME(n) \
1459 BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, n)
1462#define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c)
1463#define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c
1465#define BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method) \
1466 BaseClass##_##Method##_Benchmark
1468#define BENCHMARK_PRIVATE_DECLARE(n) \
1469 static ::benchmark::internal::Benchmark* BENCHMARK_PRIVATE_NAME(n) \
1472#ifdef BENCHMARK_HAS_CXX11
1473#define BENCHMARK(...) \
1474 BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
1475 (::benchmark::internal::RegisterBenchmarkInternal( \
1476 new ::benchmark::internal::FunctionBenchmark(#__VA_ARGS__, \
1479#define BENCHMARK(n) \
1480 BENCHMARK_PRIVATE_DECLARE(n) = \
1481 (::benchmark::internal::RegisterBenchmarkInternal( \
1482 new ::benchmark::internal::FunctionBenchmark(#n, n)))
1486#define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a))
1487#define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->Args({(a1), (a2)})
1488#define BENCHMARK_WITH_UNIT(n, t) BENCHMARK(n)->Unit((t))
1489#define BENCHMARK_RANGE(n, lo, hi) BENCHMARK(n)->Range((lo), (hi))
1490#define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \
1491 BENCHMARK(n)->RangePair({{(l1), (h1)}, {(l2), (h2)}})
1493#ifdef BENCHMARK_HAS_CXX11
1506#define BENCHMARK_CAPTURE(func, test_case_name, ...) \
1507 BENCHMARK_PRIVATE_DECLARE(func) = \
1508 (::benchmark::internal::RegisterBenchmarkInternal( \
1509 new ::benchmark::internal::FunctionBenchmark( \
1510 #func "/" #test_case_name, \
1511 [](::benchmark::State& st) { func(st, __VA_ARGS__); })))
1523#define BENCHMARK_TEMPLATE1(n, a) \
1524 BENCHMARK_PRIVATE_DECLARE(n) = \
1525 (::benchmark::internal::RegisterBenchmarkInternal( \
1526 new ::benchmark::internal::FunctionBenchmark(#n "<" #a ">", n<a>)))
1528#define BENCHMARK_TEMPLATE2(n, a, b) \
1529 BENCHMARK_PRIVATE_DECLARE(n) = \
1530 (::benchmark::internal::RegisterBenchmarkInternal( \
1531 new ::benchmark::internal::FunctionBenchmark(#n "<" #a "," #b ">", \
1534#ifdef BENCHMARK_HAS_CXX11
1535#define BENCHMARK_TEMPLATE(n, ...) \
1536 BENCHMARK_PRIVATE_DECLARE(n) = \
1537 (::benchmark::internal::RegisterBenchmarkInternal( \
1538 new ::benchmark::internal::FunctionBenchmark( \
1539 #n "<" #__VA_ARGS__ ">", n<__VA_ARGS__>)))
1541#define BENCHMARK_TEMPLATE(n, a) BENCHMARK_TEMPLATE1(n, a)
1544#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1545 class BaseClass##_##Method##_Benchmark : public BaseClass { \
1547 BaseClass##_##Method##_Benchmark() { \
1548 this->SetName(#BaseClass "/" #Method); \
1552 void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \
1555#define BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1556 class BaseClass##_##Method##_Benchmark : public BaseClass<a> { \
1558 BaseClass##_##Method##_Benchmark() { \
1559 this->SetName(#BaseClass "<" #a ">/" #Method); \
1563 void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \
1566#define BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1567 class BaseClass##_##Method##_Benchmark : public BaseClass<a, b> { \
1569 BaseClass##_##Method##_Benchmark() { \
1570 this->SetName(#BaseClass "<" #a "," #b ">/" #Method); \
1574 void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \
1577#ifdef BENCHMARK_HAS_CXX11
1578#define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, ...) \
1579 class BaseClass##_##Method##_Benchmark : public BaseClass<__VA_ARGS__> { \
1581 BaseClass##_##Method##_Benchmark() { \
1582 this->SetName(#BaseClass "<" #__VA_ARGS__ ">/" #Method); \
1586 void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \
1589#define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(n, a) \
1590 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(n, a)
1593#define BENCHMARK_DEFINE_F(BaseClass, Method) \
1594 BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1595 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1597#define BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a) \
1598 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1599 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1601#define BENCHMARK_TEMPLATE2_DEFINE_F(BaseClass, Method, a, b) \
1602 BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1603 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1605#ifdef BENCHMARK_HAS_CXX11
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_TEMPLATE_DEFINE_F(BaseClass, Method, a) \
1611 BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a)
1614#define BENCHMARK_REGISTER_F(BaseClass, Method) \
1615 BENCHMARK_PRIVATE_REGISTER_F(BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method))
1617#define BENCHMARK_PRIVATE_REGISTER_F(TestName) \
1618 BENCHMARK_PRIVATE_DECLARE(TestName) = \
1619 (::benchmark::internal::RegisterBenchmarkInternal(new TestName()))
1622#define BENCHMARK_F(BaseClass, Method) \
1623 BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1624 BENCHMARK_REGISTER_F(BaseClass, Method); \
1625 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1627#define BENCHMARK_TEMPLATE1_F(BaseClass, Method, a) \
1628 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1629 BENCHMARK_REGISTER_F(BaseClass, Method); \
1630 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1632#define BENCHMARK_TEMPLATE2_F(BaseClass, Method, a, b) \
1633 BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1634 BENCHMARK_REGISTER_F(BaseClass, Method); \
1635 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1637#ifdef BENCHMARK_HAS_CXX11
1638#define BENCHMARK_TEMPLATE_F(BaseClass, Method, ...) \
1639 BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \
1640 BENCHMARK_REGISTER_F(BaseClass, Method); \
1641 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1643#define BENCHMARK_TEMPLATE_F(BaseClass, Method, a) \
1644 BENCHMARK_TEMPLATE1_F(BaseClass, Method, a)
1649#define BENCHMARK_MAIN() \
1650 int main(int argc, char** argv) { \
1651 char arg0_default[] = "benchmark"; \
1652 char* args_default = arg0_default; \
1655 argv = &args_default; \
1657 ::benchmark::Initialize(&argc, argv); \
1658 if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; \
1659 ::benchmark::RunSpecifiedBenchmarks(); \
1660 ::benchmark::Shutdown(); \
1663 int main(int, char**)
1668namespace benchmark {
1678 enum Scaling { UNKNOWN, ENABLED, DISABLED };
1682 double cycles_per_second;
1683 std::vector<CacheInfo> caches;
1684 std::vector<double> load_avg;
1690 BENCHMARK_DISALLOW_COPY_AND_ASSIGN(
CPUInfo);
1700 BENCHMARK_DISALLOW_COPY_AND_ASSIGN(
SystemInfo);
1707 std::string function_name;
1709 std::string min_time;
1710 std::string min_warmup_time;
1711 std::string iterations;
1712 std::string repetitions;
1713 std::string time_type;
1714 std::string threads;
1718 std::string str()
const;
1732 size_t name_field_width;
1733 static const char* executable_name;
1738 static const int64_t no_repetition_index = -1;
1739 enum RunType { RT_Iteration, RT_Aggregate };
1742 : run_type(RT_Iteration),
1743 aggregate_unit(kTime),
1744 skipped(internal::NotSkipped),
1747 time_unit(GetDefaultTimeUnit()),
1748 real_accumulated_time(0),
1749 cpu_accumulated_time(0),
1750 max_heapbytes_used(0),
1752 complexity_lambda(),
1754 report_big_o(
false),
1756 memory_result(NULL),
1757 allocs_per_iter(0.0) {}
1759 std::string benchmark_name()
const;
1761 int64_t family_index;
1762 int64_t per_family_instance_index;
1764 std::string aggregate_name;
1765 StatisticUnit aggregate_unit;
1766 std::string report_label;
1767 internal::Skipped skipped;
1768 std::string skip_message;
1770 IterationCount iterations;
1772 int64_t repetition_index;
1773 int64_t repetitions;
1775 double real_accumulated_time;
1776 double cpu_accumulated_time;
1782 double GetAdjustedRealTime()
const;
1788 double GetAdjustedCPUTime()
const;
1791 double max_heapbytes_used;
1795 BigOFunc* complexity_lambda;
1796 int64_t complexity_n;
1799 const std::vector<internal::Statistics>* statistics;
1805 UserCounters counters;
1809 double allocs_per_iter;
1822 std::vector<BenchmarkReporter::Run> Runs;
1835 virtual bool ReportContext(
const Context& context) = 0;
1839 virtual void ReportRunsConfig(
double ,
1850 virtual void ReportRuns(
const std::vector<Run>& report) = 0;
1854 virtual void Finalize() {}
1858 void SetOutputStream(std::ostream* out) {
1860 output_stream_ = out;
1865 void SetErrorStream(std::ostream* err) {
1867 error_stream_ = err;
1870 std::ostream& GetOutputStream()
const {
return *output_stream_; }
1872 std::ostream& GetErrorStream()
const {
return *error_stream_; }
1874 virtual ~BenchmarkReporter();
1879 static void PrintBasicContext(std::ostream* out, Context
const& context);
1882 std::ostream* output_stream_;
1883 std::ostream* error_stream_;
1890 enum OutputOptions {
1894 OO_ColorTabular = OO_Color | OO_Tabular,
1895 OO_Defaults = OO_ColorTabular
1898 : output_options_(opts_), name_field_width_(0), printed_header_(
false) {}
1900 bool ReportContext(
const Context& context) BENCHMARK_OVERRIDE;
1901 void ReportRuns(
const std::vector<Run>& reports) BENCHMARK_OVERRIDE;
1904 virtual void PrintRunData(
const Run& report);
1905 virtual void PrintHeader(
const Run& report);
1907 OutputOptions output_options_;
1908 size_t name_field_width_;
1909 UserCounters prev_counters_;
1910 bool printed_header_;
1916 bool ReportContext(
const Context& context) BENCHMARK_OVERRIDE;
1917 void ReportRuns(
const std::vector<Run>& reports) BENCHMARK_OVERRIDE;
1918 void Finalize() BENCHMARK_OVERRIDE;
1921 void PrintRunData(
const Run& report);
1926class BENCHMARK_EXPORT BENCHMARK_DEPRECATED_MSG(
1927 "The CSV Reporter will be removed in a future release") CSVReporter
1930 CSVReporter() : printed_header_(false) {}
1931 bool ReportContext(
const Context& context) BENCHMARK_OVERRIDE;
1932 void ReportRuns(
const std::vector<Run>& reports) BENCHMARK_OVERRIDE;
1935 void PrintRunData(
const Run& report);
1937 bool printed_header_;
1938 std::set<std::string> user_counter_names_;
1941inline const char* GetTimeUnitString(TimeUnit unit) {
1952 BENCHMARK_UNREACHABLE();
1955inline double GetTimeUnitMultiplier(TimeUnit unit) {
1966 BENCHMARK_UNREACHABLE();
1979std::vector<int64_t> CreateRange(int64_t lo, int64_t hi,
int multi);
1983std::vector<int64_t> CreateDenseRange(int64_t start, int64_t limit,
int step);
1987#if defined(_MSC_VER)
Definition benchmark.h:1726
Definition benchmark.h:1888
Definition benchmark.h:598
Definition benchmark.h:1418
Definition benchmark.h:1913
Definition benchmark.h:375
Definition benchmark.h:725
Definition benchmark_api_internal.h:18
Definition perf_counters.h:149
Definition thread_manager.h:12
Definition thread_timer.h:10
Definition benchmark.h:1706
Definition benchmark.h:1728
Definition benchmark.h:1812
Definition benchmark.h:1737
Definition benchmark.h:1671
Definition benchmark.h:1670
Definition benchmark.h:379
Definition benchmark.h:1024
Definition benchmark.h:1023
Definition benchmark.h:1694
Definition benchmark.h:676