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> 199 #if defined(_MSC_VER) 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__) 275 #ifndef __has_builtin 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 293 #if defined(__GNUC__) 295 #if defined(__i386__) || defined(__x86_64__) 296 #define BENCHMARK_INTERNAL_CACHELINE_SIZE 64 297 #elif defined(__powerpc64__) 298 #define BENCHMARK_INTERNAL_CACHELINE_SIZE 128 299 #elif defined(__aarch64__) 300 #define BENCHMARK_INTERNAL_CACHELINE_SIZE 64 301 #elif defined(__arm__) 306 #if defined(__ARM_ARCH_5T__) 307 #define BENCHMARK_INTERNAL_CACHELINE_SIZE 32 308 #elif defined(__ARM_ARCH_7A__) 309 #define BENCHMARK_INTERNAL_CACHELINE_SIZE 64 314 #ifndef BENCHMARK_INTERNAL_CACHELINE_SIZE 317 #define BENCHMARK_INTERNAL_CACHELINE_SIZE 64 320 #if defined(__GNUC__) 323 #define BENCHMARK_INTERNAL_CACHELINE_ALIGNED \ 324 __attribute__((aligned(BENCHMARK_INTERNAL_CACHELINE_SIZE))) 325 #elif defined(_MSC_VER) 326 #define BENCHMARK_INTERNAL_CACHELINE_ALIGNED \ 327 __declspec(align(BENCHMARK_INTERNAL_CACHELINE_SIZE)) 329 #define BENCHMARK_INTERNAL_CACHELINE_ALIGNED 332 #if defined(_MSC_VER) 333 #pragma warning(push) 335 #pragma warning(disable : 4251) 339 class BenchmarkReporter;
342 const char kDefaultMinTimeStr[] =
"0.5s";
345 BENCHMARK_EXPORT std::string GetBenchmarkVersion();
347 BENCHMARK_EXPORT
void PrintDefaultHelp();
349 BENCHMARK_EXPORT
void Initialize(
int* argc,
char** argv,
350 void (*HelperPrinterf)() = PrintDefaultHelp);
351 BENCHMARK_EXPORT
void Shutdown();
355 BENCHMARK_EXPORT
bool ReportUnrecognizedArguments(
int argc,
char** argv);
358 BENCHMARK_EXPORT std::string GetBenchmarkFilter();
364 BENCHMARK_EXPORT
void SetBenchmarkFilter(std::string value);
367 BENCHMARK_EXPORT int32_t GetBenchmarkVerbosity();
372 BENCHMARK_EXPORT BenchmarkReporter* CreateDefaultDisplayReporter();
390 BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks();
391 BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks(std::string spec);
393 BENCHMARK_EXPORT
size_t 394 RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter);
395 BENCHMARK_EXPORT
size_t 396 RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, std::string spec);
398 BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks(
399 BenchmarkReporter* display_reporter, BenchmarkReporter* file_reporter);
400 BENCHMARK_EXPORT
size_t 401 RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
402 BenchmarkReporter* file_reporter, std::string spec);
406 enum TimeUnit { kNanosecond, kMicrosecond, kMillisecond, kSecond };
408 BENCHMARK_EXPORT TimeUnit GetDefaultTimeUnit();
412 BENCHMARK_EXPORT
void SetDefaultTimeUnit(TimeUnit unit);
419 static const int64_t TombstoneValue;
425 total_allocated_bytes(TombstoneValue),
426 net_heap_growth(TombstoneValue) {}
432 int64_t max_bytes_used;
436 int64_t total_allocated_bytes;
441 int64_t net_heap_growth;
447 virtual void Start() = 0;
450 virtual void Stop(Result& result) = 0;
456 void RegisterMemoryManager(MemoryManager* memory_manager);
466 virtual void AfterSetupStart() = 0;
470 virtual void BeforeTeardownStop() = 0;
480 void AddCustomContext(
const std::string& key,
const std::string& value);
485 class BenchmarkFamilies;
487 BENCHMARK_EXPORT std::map<std::string, std::string>*& GetGlobalContext();
490 void UseCharPointer(
char const volatile*);
494 BENCHMARK_EXPORT Benchmark* RegisterBenchmarkInternal(Benchmark*);
497 BENCHMARK_EXPORT
int InitializeStreams();
498 BENCHMARK_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 509 #ifdef BENCHMARK_HAS_CXX11 510 inline BENCHMARK_ALWAYS_INLINE
void ClobberMemory() {
511 std::atomic_signal_fence(std::memory_order_acq_rel);
519 #ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY 520 #if !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER) 522 BENCHMARK_DEPRECATED_MSG(
523 "The const-ref version of this method can permit " 524 "undesired compiler optimizations in benchmarks")
525 inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
526 asm volatile(
"" : :
"r,m"(value) :
"memory");
530 inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp& value) {
531 #if defined(__clang__) 532 asm volatile(
"" :
"+r,m"(value) : :
"memory");
534 asm volatile(
"" :
"+m,r"(value) : :
"memory");
538 #ifdef BENCHMARK_HAS_CXX11 540 inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp&& value) {
541 #if defined(__clang__) 542 asm volatile(
"" :
"+r,m"(value) : :
"memory");
544 asm volatile(
"" :
"+m,r"(value) : :
"memory");
548 #elif defined(BENCHMARK_HAS_CXX11) && (__GNUC__ >= 5) 552 BENCHMARK_DEPRECATED_MSG(
553 "The const-ref version of this method can permit " 554 "undesired compiler optimizations in benchmarks")
555 inline BENCHMARK_ALWAYS_INLINE
556 typename
std::enable_if<
std::is_trivially_copyable<Tp>::value &&
557 (sizeof(Tp) <= sizeof(Tp*))>::type
558 DoNotOptimize(Tp const& value) {
559 asm volatile(
"" : :
"r,m"(value) :
"memory");
563 BENCHMARK_DEPRECATED_MSG(
564 "The const-ref version of this method can permit " 565 "undesired compiler optimizations in benchmarks")
566 inline BENCHMARK_ALWAYS_INLINE
567 typename
std::enable_if<!
std::is_trivially_copyable<Tp>::value ||
568 (sizeof(Tp) > sizeof(Tp*))>::type
569 DoNotOptimize(Tp const& value) {
570 asm volatile(
"" : :
"m"(value) :
"memory");
574 inline BENCHMARK_ALWAYS_INLINE
575 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
576 (
sizeof(Tp) <=
sizeof(Tp*))>::type
577 DoNotOptimize(Tp& value) {
578 asm volatile(
"" :
"+m,r"(value) : :
"memory");
582 inline BENCHMARK_ALWAYS_INLINE
583 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
584 (
sizeof(Tp) >
sizeof(Tp*))>::type
585 DoNotOptimize(Tp& value) {
586 asm volatile(
"" :
"+m"(value) : :
"memory");
590 inline BENCHMARK_ALWAYS_INLINE
591 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
592 (
sizeof(Tp) <=
sizeof(Tp*))>::type
593 DoNotOptimize(Tp&& value) {
594 asm volatile(
"" :
"+m,r"(value) : :
"memory");
598 inline BENCHMARK_ALWAYS_INLINE
599 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
600 (
sizeof(Tp) >
sizeof(Tp*))>::type
601 DoNotOptimize(Tp&& value) {
602 asm volatile(
"" :
"+m"(value) : :
"memory");
610 BENCHMARK_DEPRECATED_MSG(
611 "The const-ref version of this method can permit " 612 "undesired compiler optimizations in benchmarks")
613 inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
614 asm volatile(
"" : :
"m"(value) :
"memory");
618 inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp& value) {
619 asm volatile(
"" :
"+m"(value) : :
"memory");
622 #ifdef BENCHMARK_HAS_CXX11 624 inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp&& value) {
625 asm volatile(
"" :
"+m"(value) : :
"memory");
630 #ifndef BENCHMARK_HAS_CXX11 631 inline BENCHMARK_ALWAYS_INLINE
void ClobberMemory() {
632 asm volatile(
"" : : :
"memory");
635 #elif defined(_MSC_VER) 637 BENCHMARK_DEPRECATED_MSG(
638 "The const-ref version of this method can permit " 639 "undesired compiler optimizations in benchmarks")
640 inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
641 internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
645 #ifndef BENCHMARK_HAS_CXX11 646 inline BENCHMARK_ALWAYS_INLINE
void ClobberMemory() { _ReadWriteBarrier(); }
649 #ifdef BENCHMARK_HAS_CXX11 651 inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp&& value) {
652 internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
656 BENCHMARK_DEPRECATED_MSG(
657 "The const-ref version of this method can permit " 658 "undesired compiler optimizations in benchmarks")
659 inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
660 internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
664 inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp& value) {
665 internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
681 kAvgThreads = 1 << 1,
683 kAvgThreadsRate = kIsRate | kAvgThreads,
686 kIsIterationInvariant = 1 << 2,
690 kIsIterationInvariantRate = kIsRate | kIsIterationInvariant,
693 kAvgIterations = 1 << 3,
695 kAvgIterationsRate = kIsRate | kAvgIterations,
712 BENCHMARK_ALWAYS_INLINE
713 Counter(
double v = 0., Flags f = kDefaults, OneK k = kIs1000)
714 : value(v), flags(f), oneK(k) {}
716 BENCHMARK_ALWAYS_INLINE
operator double const &()
const {
return value; }
717 BENCHMARK_ALWAYS_INLINE
operator double&() {
return value; }
722 Counter::Flags
inline operator|(
const Counter::Flags& LHS,
723 const Counter::Flags& RHS) {
724 return static_cast<Counter::Flags
>(
static_cast<int>(LHS) |
725 static_cast<int>(RHS));
729 typedef std::map<std::string, Counter> UserCounters;
735 enum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLambda };
737 typedef int64_t ComplexityN;
739 typedef int64_t IterationCount;
741 enum StatisticUnit { kTime, kPercentage };
745 typedef double(BigOFunc)(ComplexityN);
749 typedef double(StatisticsFunc)(
const std::vector<double>&);
754 StatisticsFunc* compute_;
757 Statistics(
const std::string& name, StatisticsFunc* compute,
758 StatisticUnit unit = kTime)
759 : name_(name), compute_(compute), unit_(unit) {}
767 enum AggregationReportMode
768 #if defined(BENCHMARK_HAS_CXX11) 777 ARM_Default = 1U << 0U,
779 ARM_FileReportAggregatesOnly = 1U << 1U,
781 ARM_DisplayReportAggregatesOnly = 1U << 2U,
783 ARM_ReportAggregatesOnly =
784 ARM_FileReportAggregatesOnly | ARM_DisplayReportAggregatesOnly
788 #if defined(BENCHMARK_HAS_CXX11) 799 #if defined(_MSC_VER) 800 #pragma warning(push) 802 #pragma warning(disable : 4324) 806 class BENCHMARK_EXPORT BENCHMARK_INTERNAL_CACHELINE_ALIGNED
State {
824 inline bool KeepRunning();
836 inline bool KeepRunningBatch(IterationCount n);
885 void SkipWithMessage(
const std::string& msg);
906 void SkipWithError(
const std::string& msg);
909 bool skipped()
const {
return internal::NotSkipped != skipped_; }
912 bool error_occurred()
const {
return internal::SkippedWithError == skipped_; }
921 void SetIterationTime(
double seconds);
928 BENCHMARK_ALWAYS_INLINE
929 void SetBytesProcessed(int64_t bytes) {
930 counters[
"bytes_per_second"] =
931 Counter(static_cast<double>(bytes), Counter::kIsRate, Counter::kIs1024);
934 BENCHMARK_ALWAYS_INLINE
935 int64_t bytes_processed()
const {
936 if (counters.find(
"bytes_per_second") != counters.end())
937 return static_cast<int64_t>(counters.at(
"bytes_per_second"));
946 BENCHMARK_ALWAYS_INLINE
947 void SetComplexityN(ComplexityN complexity_n) {
948 complexity_n_ = complexity_n;
951 BENCHMARK_ALWAYS_INLINE
952 ComplexityN complexity_length_n()
const {
return complexity_n_; }
960 BENCHMARK_ALWAYS_INLINE
961 void SetItemsProcessed(int64_t items) {
962 counters[
"items_per_second"] =
963 Counter(static_cast<double>(items), benchmark::Counter::kIsRate);
966 BENCHMARK_ALWAYS_INLINE
967 int64_t items_processed()
const {
968 if (counters.find(
"items_per_second") != counters.end())
969 return static_cast<int64_t>(counters.at(
"items_per_second"));
985 void SetLabel(
const std::string& label);
988 BENCHMARK_ALWAYS_INLINE
989 int64_t range(std::size_t pos = 0)
const {
990 assert(range_.size() > pos);
994 BENCHMARK_DEPRECATED_MSG(
"use 'range(0)' instead")
995 int64_t range_x()
const {
return range(0); }
997 BENCHMARK_DEPRECATED_MSG(
"use 'range(1)' instead")
998 int64_t range_y()
const {
return range(1); }
1001 BENCHMARK_ALWAYS_INLINE
1002 int threads()
const {
return threads_; }
1005 BENCHMARK_ALWAYS_INLINE
1006 int thread_index()
const {
return thread_index_; }
1008 BENCHMARK_ALWAYS_INLINE
1009 IterationCount iterations()
const {
1010 if (BENCHMARK_BUILTIN_EXPECT(!started_,
false)) {
1013 return max_iterations - total_iterations_ + batch_leftover_;
1016 BENCHMARK_ALWAYS_INLINE
1017 std::string name()
const {
return name_; }
1023 IterationCount total_iterations_;
1028 IterationCount batch_leftover_;
1031 const IterationCount max_iterations;
1036 internal::Skipped skipped_;
1039 std::vector<int64_t> range_;
1041 ComplexityN complexity_n_;
1045 UserCounters counters;
1048 State(std::string name, IterationCount max_iters,
1049 const std::vector<int64_t>& ranges,
int thread_i,
int n_threads,
1054 void StartKeepRunning();
1057 inline bool KeepRunningInternal(IterationCount n,
bool is_batch);
1058 void FinishKeepRunning();
1060 const std::string name_;
1061 const int thread_index_;
1071 #if defined(_MSC_VER) 1072 #pragma warning(pop) 1075 inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunning() {
1076 return KeepRunningInternal(1,
false);
1079 inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunningBatch(IterationCount n) {
1080 return KeepRunningInternal(n,
true);
1083 inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunningInternal(IterationCount n,
1089 assert(is_batch || n == 1);
1090 if (BENCHMARK_BUILTIN_EXPECT(total_iterations_ >= n,
true)) {
1091 total_iterations_ -= n;
1096 if (!skipped() && total_iterations_ >= n) {
1097 total_iterations_ -= n;
1102 if (is_batch && total_iterations_ != 0) {
1103 batch_leftover_ = n - total_iterations_;
1104 total_iterations_ = 0;
1107 FinishKeepRunning();
1113 typedef std::forward_iterator_tag iterator_category;
1117 typedef std::ptrdiff_t difference_type;
1121 BENCHMARK_ALWAYS_INLINE
1124 BENCHMARK_ALWAYS_INLINE
1126 : cached_(st->skipped() ? 0 : st->max_iterations), parent_(st) {}
1129 BENCHMARK_ALWAYS_INLINE
1130 Value operator*()
const {
return Value(); }
1132 BENCHMARK_ALWAYS_INLINE
1133 StateIterator& operator++() {
1134 assert(cached_ > 0);
1139 BENCHMARK_ALWAYS_INLINE
1140 bool operator!=(StateIterator
const&)
const {
1141 if (BENCHMARK_BUILTIN_EXPECT(cached_ != 0,
true))
return true;
1142 parent_->FinishKeepRunning();
1147 IterationCount cached_;
1148 State*
const parent_;
1151 inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::begin() {
1152 return StateIterator(
this);
1154 inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::end() {
1156 return StateIterator();
1159 namespace internal {
1161 typedef void(Function)(State&);
1177 Benchmark* Name(
const std::string& name);
1190 Benchmark* Range(int64_t start, int64_t limit);
1195 Benchmark* DenseRange(int64_t start, int64_t limit,
int step = 1);
1200 Benchmark* Args(
const std::vector<int64_t>& args);
1205 Benchmark* ArgPair(int64_t x, int64_t y) {
1206 std::vector<int64_t> args;
1215 Benchmark* Ranges(
const std::vector<std::pair<int64_t, int64_t> >& ranges);
1220 Benchmark* ArgsProduct(
const std::vector<std::vector<int64_t> >& arglists);
1223 Benchmark* ArgName(
const std::string& name);
1227 Benchmark* ArgNames(
const std::vector<std::string>& names);
1232 Benchmark* RangePair(int64_t lo1, int64_t hi1, int64_t lo2, int64_t hi2) {
1233 std::vector<std::pair<int64_t, int64_t> > ranges;
1234 ranges.push_back(std::make_pair(lo1, hi1));
1235 ranges.push_back(std::make_pair(lo2, hi2));
1236 return Ranges(ranges);
1263 Benchmark* RangeMultiplier(
int multiplier);
1283 Benchmark* Iterations(IterationCount n);
1294 Benchmark* ReportAggregatesOnly(
bool value =
true);
1297 Benchmark* DisplayAggregatesOnly(
bool value =
true);
1324 Benchmark* Complexity(BigO complexity = benchmark::oAuto);
1328 Benchmark* Complexity(BigOFunc* complexity);
1331 Benchmark* ComputeStatistics(
const std::string& name,
1332 StatisticsFunc* statistics,
1333 StatisticUnit unit = kTime);
1354 Benchmark* ThreadRange(
int min_threads,
int max_threads);
1360 Benchmark* DenseThreadRange(
int min_threads,
int max_threads,
int stride = 1);
1365 virtual void Run(
State& state) = 0;
1367 TimeUnit GetTimeUnit()
const;
1370 explicit Benchmark(
const std::string& name);
1371 void SetName(
const std::string& name);
1374 const char* GetName()
const;
1375 int ArgsCnt()
const;
1376 const char* GetArgName(
int arg)
const;
1383 AggregationReportMode aggregation_report_mode_;
1384 std::vector<std::string> arg_names_;
1385 std::vector<std::vector<int64_t> > args_;
1387 TimeUnit time_unit_;
1388 bool use_default_time_unit_;
1390 int range_multiplier_;
1392 double min_warmup_time_;
1393 IterationCount iterations_;
1395 bool measure_process_cpu_time_;
1396 bool use_real_time_;
1397 bool use_manual_time_;
1399 BigOFunc* complexity_lambda_;
1400 std::vector<Statistics> statistics_;
1401 std::vector<int> thread_counts_;
1404 callback_function setup_;
1405 callback_function teardown_;
1408 #if defined(BENCHMARK_HAS_CXX11) 1414 #if defined(BENCHMARK_HAS_CXX11) 1427 internal::Function* fn);
1429 #if defined(BENCHMARK_HAS_CXX11) 1430 template <
class Lambda>
1436 BENCHMARK_EXPORT
void ClearRegisteredBenchmarks();
1438 namespace internal {
1446 void Run(
State& st) BENCHMARK_OVERRIDE;
1452 #ifdef BENCHMARK_HAS_CXX11 1453 template <
class Lambda>
1454 class LambdaBenchmark :
public Benchmark {
1456 void Run(
State& st) BENCHMARK_OVERRIDE { lambda_(st); }
1459 template <
class OLambda>
1460 LambdaBenchmark(
const std::string& name, OLambda&& lam)
1461 : Benchmark(name), lambda_(
std::forward<OLambda>(lam)) {}
1463 LambdaBenchmark(LambdaBenchmark
const&) =
delete;
1465 template <
class Lam>
1466 friend Benchmark* ::benchmark::RegisterBenchmark(
const std::string&, Lam&&);
1473 inline internal::Benchmark* RegisterBenchmark(
const std::string& name,
1474 internal::Function* fn) {
1477 return internal::RegisterBenchmarkInternal(
1478 ::
new internal::FunctionBenchmark(name, fn));
1481 #ifdef BENCHMARK_HAS_CXX11 1482 template <
class Lambda>
1483 internal::Benchmark* RegisterBenchmark(
const std::string& name, Lambda&& fn) {
1485 internal::LambdaBenchmark<typename std::decay<Lambda>::type>;
1488 return internal::RegisterBenchmarkInternal(
1489 ::
new BenchType(name, std::forward<Lambda>(fn)));
1493 #if defined(BENCHMARK_HAS_CXX11) && \ 1494 (!defined(BENCHMARK_GCC_VERSION) || BENCHMARK_GCC_VERSION >= 409) 1495 template <
class Lambda,
class... Args>
1496 internal::Benchmark* RegisterBenchmark(
const std::string& name, Lambda&& fn,
1498 return benchmark::RegisterBenchmark(
1502 #define BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK 1510 void Run(
State& st) BENCHMARK_OVERRIDE {
1512 this->BenchmarkCase(st);
1517 virtual void SetUp(
const State&) {}
1518 virtual void TearDown(
const State&) {}
1520 virtual void SetUp(
State& st) { SetUp(const_cast<const State&>(st)); }
1521 virtual void TearDown(
State& st) { TearDown(const_cast<const State&>(st)); }
1524 virtual void BenchmarkCase(
State&) = 0;
1534 #if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0) 1535 #define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__ 1537 #define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__ 1541 #ifdef BENCHMARK_HAS_CXX11 1542 #define BENCHMARK_PRIVATE_NAME(...) \ 1543 BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, \ 1546 #define BENCHMARK_PRIVATE_NAME(n) \ 1547 BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, n) 1548 #endif // BENCHMARK_HAS_CXX11 1550 #define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c) 1551 #define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c 1553 #define BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method) \ 1554 BaseClass##_##Method##_Benchmark 1556 #define BENCHMARK_PRIVATE_DECLARE(n) \ 1558 static ::benchmark::internal::Benchmark* BENCHMARK_PRIVATE_NAME(n) \ 1561 #ifdef BENCHMARK_HAS_CXX11 1562 #define BENCHMARK(...) \ 1563 BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \ 1564 (::benchmark::internal::RegisterBenchmarkInternal( \ 1565 new ::benchmark::internal::FunctionBenchmark(#__VA_ARGS__, \ 1568 #define BENCHMARK(n) \ 1569 BENCHMARK_PRIVATE_DECLARE(n) = \ 1570 (::benchmark::internal::RegisterBenchmarkInternal( \ 1571 new ::benchmark::internal::FunctionBenchmark(#n, n))) 1572 #endif // BENCHMARK_HAS_CXX11 1575 #define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a)) 1576 #define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->Args({(a1), (a2)}) 1577 #define BENCHMARK_WITH_UNIT(n, t) BENCHMARK(n)->Unit((t)) 1578 #define BENCHMARK_RANGE(n, lo, hi) BENCHMARK(n)->Range((lo), (hi)) 1579 #define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \ 1580 BENCHMARK(n)->RangePair({{(l1), (h1)}, {(l2), (h2)}}) 1582 #ifdef BENCHMARK_HAS_CXX11 1595 #define BENCHMARK_CAPTURE(func, test_case_name, ...) \ 1596 BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \ 1597 (::benchmark::internal::RegisterBenchmarkInternal( \ 1598 new ::benchmark::internal::FunctionBenchmark( \ 1599 #func "/" #test_case_name, \ 1600 [](::benchmark::State& st) { func(st, __VA_ARGS__); }))) 1602 #endif // BENCHMARK_HAS_CXX11 1612 #define BENCHMARK_TEMPLATE1(n, a) \ 1613 BENCHMARK_PRIVATE_DECLARE(n) = \ 1614 (::benchmark::internal::RegisterBenchmarkInternal( \ 1615 new ::benchmark::internal::FunctionBenchmark(#n "<" #a ">", n<a>))) 1617 #define BENCHMARK_TEMPLATE2(n, a, b) \ 1618 BENCHMARK_PRIVATE_DECLARE(n) = \ 1619 (::benchmark::internal::RegisterBenchmarkInternal( \ 1620 new ::benchmark::internal::FunctionBenchmark(#n "<" #a "," #b ">", \ 1623 #ifdef BENCHMARK_HAS_CXX11 1624 #define BENCHMARK_TEMPLATE(n, ...) \ 1625 BENCHMARK_PRIVATE_DECLARE(n) = \ 1626 (::benchmark::internal::RegisterBenchmarkInternal( \ 1627 new ::benchmark::internal::FunctionBenchmark( \ 1628 #n "<" #__VA_ARGS__ ">", n<__VA_ARGS__>))) 1630 #define BENCHMARK_TEMPLATE(n, a) BENCHMARK_TEMPLATE1(n, a) 1633 #ifdef BENCHMARK_HAS_CXX11 1646 #define BENCHMARK_TEMPLATE1_CAPTURE(func, a, test_case_name, ...) \ 1647 BENCHMARK_CAPTURE(func<a>, test_case_name, __VA_ARGS__) 1649 #define BENCHMARK_TEMPLATE2_CAPTURE(func, a, b, test_case_name, ...) \ 1650 BENCHMARK_PRIVATE_DECLARE(func) = \ 1651 (::benchmark::internal::RegisterBenchmarkInternal( \ 1652 new ::benchmark::internal::FunctionBenchmark( \ 1653 #func "<" #a "," #b ">" \ 1654 "/" #test_case_name, \ 1655 [](::benchmark::State& st) { func<a, b>(st, __VA_ARGS__); }))) 1656 #endif // BENCHMARK_HAS_CXX11 1658 #define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \ 1659 class BaseClass##_##Method##_Benchmark : public BaseClass { \ 1661 BaseClass##_##Method##_Benchmark() { \ 1662 this->SetName(#BaseClass "/" #Method); \ 1666 void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \ 1669 #define BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \ 1670 class BaseClass##_##Method##_Benchmark : public BaseClass<a> { \ 1672 BaseClass##_##Method##_Benchmark() { \ 1673 this->SetName(#BaseClass "<" #a ">/" #Method); \ 1677 void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \ 1680 #define BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \ 1681 class BaseClass##_##Method##_Benchmark : public BaseClass<a, b> { \ 1683 BaseClass##_##Method##_Benchmark() { \ 1684 this->SetName(#BaseClass "<" #a "," #b ">/" #Method); \ 1688 void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \ 1691 #ifdef BENCHMARK_HAS_CXX11 1692 #define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, ...) \ 1693 class BaseClass##_##Method##_Benchmark : public BaseClass<__VA_ARGS__> { \ 1695 BaseClass##_##Method##_Benchmark() { \ 1696 this->SetName(#BaseClass "<" #__VA_ARGS__ ">/" #Method); \ 1700 void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \ 1703 #define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(n, a) \ 1704 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(n, a) 1707 #define BENCHMARK_DEFINE_F(BaseClass, Method) \ 1708 BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \ 1709 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase 1711 #define BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a) \ 1712 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \ 1713 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase 1715 #define BENCHMARK_TEMPLATE2_DEFINE_F(BaseClass, Method, a, b) \ 1716 BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \ 1717 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase 1719 #ifdef BENCHMARK_HAS_CXX11 1720 #define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, ...) \ 1721 BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \ 1722 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase 1724 #define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, a) \ 1725 BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a) 1728 #define BENCHMARK_REGISTER_F(BaseClass, Method) \ 1729 BENCHMARK_PRIVATE_REGISTER_F(BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)) 1731 #define BENCHMARK_PRIVATE_REGISTER_F(TestName) \ 1732 BENCHMARK_PRIVATE_DECLARE(TestName) = \ 1733 (::benchmark::internal::RegisterBenchmarkInternal(new TestName())) 1736 #define BENCHMARK_F(BaseClass, Method) \ 1737 BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \ 1738 BENCHMARK_REGISTER_F(BaseClass, Method); \ 1739 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase 1741 #define BENCHMARK_TEMPLATE1_F(BaseClass, Method, a) \ 1742 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \ 1743 BENCHMARK_REGISTER_F(BaseClass, Method); \ 1744 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase 1746 #define BENCHMARK_TEMPLATE2_F(BaseClass, Method, a, b) \ 1747 BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \ 1748 BENCHMARK_REGISTER_F(BaseClass, Method); \ 1749 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase 1751 #ifdef BENCHMARK_HAS_CXX11 1752 #define BENCHMARK_TEMPLATE_F(BaseClass, Method, ...) \ 1753 BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \ 1754 BENCHMARK_REGISTER_F(BaseClass, Method); \ 1755 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase 1757 #define BENCHMARK_TEMPLATE_F(BaseClass, Method, a) \ 1758 BENCHMARK_TEMPLATE1_F(BaseClass, Method, a) 1763 #define BENCHMARK_MAIN() \ 1764 int main(int argc, char** argv) { \ 1765 char arg0_default[] = "benchmark"; \ 1766 char* args_default = arg0_default; \ 1769 argv = &args_default; \ 1771 ::benchmark::Initialize(&argc, argv); \ 1772 if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; \ 1773 ::benchmark::RunSpecifiedBenchmarks(); \ 1774 ::benchmark::Shutdown(); \ 1777 int main(int, char**) 1792 enum Scaling { UNKNOWN, ENABLED, DISABLED };
1796 double cycles_per_second;
1797 std::vector<CacheInfo> caches;
1798 std::vector<double> load_avg;
1804 BENCHMARK_DISALLOW_COPY_AND_ASSIGN(
CPUInfo);
1814 BENCHMARK_DISALLOW_COPY_AND_ASSIGN(
SystemInfo);
1821 std::string function_name;
1823 std::string min_time;
1824 std::string min_warmup_time;
1825 std::string iterations;
1826 std::string repetitions;
1827 std::string time_type;
1828 std::string threads;
1832 std::string str()
const;
1846 size_t name_field_width;
1847 static const char* executable_name;
1852 static const int64_t no_repetition_index = -1;
1853 enum RunType { RT_Iteration, RT_Aggregate };
1856 : run_type(RT_Iteration),
1857 aggregate_unit(kTime),
1858 skipped(internal::NotSkipped),
1861 time_unit(GetDefaultTimeUnit()),
1862 real_accumulated_time(0),
1863 cpu_accumulated_time(0),
1864 max_heapbytes_used(0),
1865 use_real_time_for_initial_big_o(
false),
1867 complexity_lambda(),
1869 report_big_o(
false),
1871 memory_result(NULL),
1872 allocs_per_iter(0.0) {}
1874 std::string benchmark_name()
const;
1876 int64_t family_index;
1877 int64_t per_family_instance_index;
1879 std::string aggregate_name;
1880 StatisticUnit aggregate_unit;
1881 std::string report_label;
1882 internal::Skipped skipped;
1883 std::string skip_message;
1885 IterationCount iterations;
1887 int64_t repetition_index;
1888 int64_t repetitions;
1890 double real_accumulated_time;
1891 double cpu_accumulated_time;
1897 double GetAdjustedRealTime()
const;
1903 double GetAdjustedCPUTime()
const;
1906 double max_heapbytes_used;
1910 bool use_real_time_for_initial_big_o;
1914 BigOFunc* complexity_lambda;
1915 ComplexityN complexity_n;
1918 const std::vector<internal::Statistics>* statistics;
1924 UserCounters counters;
1928 double allocs_per_iter;
1941 std::vector<BenchmarkReporter::Run> Runs;
1954 virtual bool ReportContext(
const Context& context) = 0;
1958 virtual void ReportRunsConfig(
double ,
1969 virtual void ReportRuns(
const std::vector<Run>& report) = 0;
1973 virtual void Finalize() {}
1977 void SetOutputStream(std::ostream* out) {
1979 output_stream_ = out;
1984 void SetErrorStream(std::ostream* err) {
1986 error_stream_ = err;
1989 std::ostream& GetOutputStream()
const {
return *output_stream_; }
1991 std::ostream& GetErrorStream()
const {
return *error_stream_; }
1993 virtual ~BenchmarkReporter();
1998 static void PrintBasicContext(std::ostream* out, Context
const& context);
2001 std::ostream* output_stream_;
2002 std::ostream* error_stream_;
2009 enum OutputOptions {
2013 OO_ColorTabular = OO_Color | OO_Tabular,
2014 OO_Defaults = OO_ColorTabular
2017 : output_options_(opts_), name_field_width_(0), printed_header_(
false) {}
2019 bool ReportContext(
const Context& context) BENCHMARK_OVERRIDE;
2020 void ReportRuns(
const std::vector<Run>& reports) BENCHMARK_OVERRIDE;
2023 virtual void PrintRunData(
const Run& report);
2024 virtual void PrintHeader(
const Run& report);
2026 OutputOptions output_options_;
2027 size_t name_field_width_;
2028 UserCounters prev_counters_;
2029 bool printed_header_;
2035 bool ReportContext(
const Context& context) BENCHMARK_OVERRIDE;
2036 void ReportRuns(
const std::vector<Run>& reports) BENCHMARK_OVERRIDE;
2037 void Finalize() BENCHMARK_OVERRIDE;
2040 void PrintRunData(
const Run& report);
2045 class BENCHMARK_EXPORT BENCHMARK_DEPRECATED_MSG(
2046 "The CSV Reporter will be removed in a future release") CSVReporter
2049 CSVReporter() : printed_header_(false) {}
2050 bool ReportContext(
const Context& context) BENCHMARK_OVERRIDE;
2051 void ReportRuns(
const std::vector<Run>& reports) BENCHMARK_OVERRIDE;
2054 void PrintRunData(
const Run& report);
2056 bool printed_header_;
2057 std::set<std::string> user_counter_names_;
2060 inline const char* GetTimeUnitString(TimeUnit unit) {
2071 BENCHMARK_UNREACHABLE();
2074 inline double GetTimeUnitMultiplier(TimeUnit unit) {
2085 BENCHMARK_UNREACHABLE();
2098 std::vector<int64_t> CreateRange(int64_t lo, int64_t hi,
int multi);
2102 std::vector<int64_t> CreateDenseRange(int64_t start, int64_t limit,
int step);
2106 #if defined(_MSC_VER) 2107 #pragma warning(pop) 2110 #endif // BENCHMARK_BENCHMARK_H_ Definition: benchmark.h:461
Definition: benchmark.h:1784
Definition: thread_timer.h:10
Definition: benchmark_api_internal.h:18
Definition: benchmark.h:672
Definition: benchmark.h:1111
Definition: benchmark.h:1842
Definition: benchmark.h:1840
Definition: benchmark.h:421
Definition: benchmark.h:2032
Definition: benchmark.h:2007
Definition: benchmark.h:1820
Definition: benchmark.h:1931
Definition: perf_counters.h:149
Definition: benchmark.h:1851
Definition: benchmark.h:1808
Definition: benchmark.h:338
Definition: benchmark_register.cc:73
Definition: benchmark.h:752
Definition: benchmark.h:417
Definition: benchmark.h:806
Definition: benchmark.h:1441
Definition: benchmark.h:1169
Definition: benchmark.h:1506
Definition: benchmark.h:1112
Definition: thread_manager.h:12
Definition: benchmark.h:1785