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(_MSC_VER)
294 #pragma warning(push)
296 #pragma warning(disable : 4251)
299 namespace benchmark {
300 class BenchmarkReporter;
303 const char kDefaultMinTimeStr[] =
"0.5s";
306 BENCHMARK_EXPORT std::string GetBenchmarkVersion();
308 BENCHMARK_EXPORT
void PrintDefaultHelp();
310 BENCHMARK_EXPORT
void Initialize(
int* argc,
char** argv,
311 void (*HelperPrinterf)() = PrintDefaultHelp);
312 BENCHMARK_EXPORT
void Shutdown();
316 BENCHMARK_EXPORT
bool ReportUnrecognizedArguments(
int argc,
char** argv);
319 BENCHMARK_EXPORT std::string GetBenchmarkFilter();
325 BENCHMARK_EXPORT
void SetBenchmarkFilter(std::string value);
328 BENCHMARK_EXPORT int32_t GetBenchmarkVerbosity();
333 BENCHMARK_EXPORT BenchmarkReporter* CreateDefaultDisplayReporter();
351 BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks();
352 BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks(std::string spec);
354 BENCHMARK_EXPORT
size_t
355 RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter);
356 BENCHMARK_EXPORT
size_t
357 RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, std::string spec);
359 BENCHMARK_EXPORT
size_t RunSpecifiedBenchmarks(
360 BenchmarkReporter* display_reporter, BenchmarkReporter* file_reporter);
361 BENCHMARK_EXPORT
size_t
362 RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
363 BenchmarkReporter* file_reporter, std::string spec);
367 enum TimeUnit { kNanosecond, kMicrosecond, kMillisecond, kSecond };
369 BENCHMARK_EXPORT TimeUnit GetDefaultTimeUnit();
373 BENCHMARK_EXPORT
void SetDefaultTimeUnit(TimeUnit unit);
380 static const int64_t TombstoneValue;
386 total_allocated_bytes(TombstoneValue),
387 net_heap_growth(TombstoneValue) {}
393 int64_t max_bytes_used;
397 int64_t total_allocated_bytes;
402 int64_t net_heap_growth;
408 virtual void Start() = 0;
411 virtual void Stop(Result& result) = 0;
417 void RegisterMemoryManager(MemoryManager* memory_manager);
427 virtual void AfterSetupStart() = 0;
431 virtual void BeforeTeardownStop() = 0;
441 void AddCustomContext(
const std::string& key,
const std::string& value);
446 class BenchmarkFamilies;
448 BENCHMARK_EXPORT std::map<std::string, std::string>*& GetGlobalContext();
451 void UseCharPointer(
char const volatile*);
455 BENCHMARK_EXPORT Benchmark* RegisterBenchmarkInternal(Benchmark*);
458 BENCHMARK_EXPORT
int InitializeStreams();
459 BENCHMARK_UNUSED
static int stream_init_anchor = InitializeStreams();
463 #if (!defined(__GNUC__) && !defined(__clang__)) || defined(__pnacl__) || \
464 defined(__EMSCRIPTEN__)
465 #define BENCHMARK_HAS_NO_INLINE_ASSEMBLY
470 #ifdef BENCHMARK_HAS_CXX11
471 inline BENCHMARK_ALWAYS_INLINE
void ClobberMemory() {
472 std::atomic_signal_fence(std::memory_order_acq_rel);
480 #ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY
481 #if !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER)
483 BENCHMARK_DEPRECATED_MSG(
484 "The const-ref version of this method can permit "
485 "undesired compiler optimizations in benchmarks")
486 inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
487 asm volatile(
"" : :
"r,m"(value) :
"memory");
491 inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp& value) {
492 #if defined(__clang__)
493 asm volatile(
"" :
"+r,m"(value) : :
"memory");
495 asm volatile(
"" :
"+m,r"(value) : :
"memory");
499 #ifdef BENCHMARK_HAS_CXX11
501 inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp&& value) {
502 #if defined(__clang__)
503 asm volatile(
"" :
"+r,m"(value) : :
"memory");
505 asm volatile(
"" :
"+m,r"(value) : :
"memory");
509 #elif defined(BENCHMARK_HAS_CXX11) && (__GNUC__ >= 5)
513 BENCHMARK_DEPRECATED_MSG(
514 "The const-ref version of this method can permit "
515 "undesired compiler optimizations in benchmarks")
516 inline BENCHMARK_ALWAYS_INLINE
517 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
518 (sizeof(Tp) <= sizeof(Tp*))>::type
519 DoNotOptimize(Tp const& value) {
520 asm volatile(
"" : :
"r,m"(value) :
"memory");
524 BENCHMARK_DEPRECATED_MSG(
525 "The const-ref version of this method can permit "
526 "undesired compiler optimizations in benchmarks")
527 inline BENCHMARK_ALWAYS_INLINE
528 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
529 (sizeof(Tp) > sizeof(Tp*))>::type
530 DoNotOptimize(Tp const& value) {
531 asm volatile(
"" : :
"m"(value) :
"memory");
535 inline BENCHMARK_ALWAYS_INLINE
536 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
537 (
sizeof(Tp) <=
sizeof(Tp*))>::type
538 DoNotOptimize(Tp& value) {
539 asm volatile(
"" :
"+m,r"(value) : :
"memory");
543 inline BENCHMARK_ALWAYS_INLINE
544 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
545 (
sizeof(Tp) >
sizeof(Tp*))>::type
546 DoNotOptimize(Tp& value) {
547 asm volatile(
"" :
"+m"(value) : :
"memory");
551 inline BENCHMARK_ALWAYS_INLINE
552 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
553 (
sizeof(Tp) <=
sizeof(Tp*))>::type
554 DoNotOptimize(Tp&& value) {
555 asm volatile(
"" :
"+m,r"(value) : :
"memory");
559 inline BENCHMARK_ALWAYS_INLINE
560 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
561 (
sizeof(Tp) >
sizeof(Tp*))>::type
562 DoNotOptimize(Tp&& value) {
563 asm volatile(
"" :
"+m"(value) : :
"memory");
571 BENCHMARK_DEPRECATED_MSG(
572 "The const-ref version of this method can permit "
573 "undesired compiler optimizations in benchmarks")
574 inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
575 asm volatile(
"" : :
"m"(value) :
"memory");
579 inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp& value) {
580 asm volatile(
"" :
"+m"(value) : :
"memory");
583 #ifdef BENCHMARK_HAS_CXX11
585 inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp&& value) {
586 asm volatile(
"" :
"+m"(value) : :
"memory");
591 #ifndef BENCHMARK_HAS_CXX11
592 inline BENCHMARK_ALWAYS_INLINE
void ClobberMemory() {
593 asm volatile(
"" : : :
"memory");
596 #elif defined(_MSC_VER)
598 BENCHMARK_DEPRECATED_MSG(
599 "The const-ref version of this method can permit "
600 "undesired compiler optimizations in benchmarks")
601 inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
602 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
606 #ifndef BENCHMARK_HAS_CXX11
607 inline BENCHMARK_ALWAYS_INLINE
void ClobberMemory() { _ReadWriteBarrier(); }
610 #ifdef BENCHMARK_HAS_CXX11
612 inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp&& value) {
613 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
617 BENCHMARK_DEPRECATED_MSG(
618 "The const-ref version of this method can permit "
619 "undesired compiler optimizations in benchmarks")
620 inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp const& value) {
621 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
625 inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp& value) {
626 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
642 kAvgThreads = 1 << 1,
644 kAvgThreadsRate = kIsRate | kAvgThreads,
647 kIsIterationInvariant = 1 << 2,
651 kIsIterationInvariantRate = kIsRate | kIsIterationInvariant,
654 kAvgIterations = 1 << 3,
656 kAvgIterationsRate = kIsRate | kAvgIterations,
673 BENCHMARK_ALWAYS_INLINE
674 Counter(
double v = 0., Flags f = kDefaults, OneK k = kIs1000)
675 : value(v), flags(f), oneK(k) {}
677 BENCHMARK_ALWAYS_INLINE
operator double const &()
const {
return value; }
678 BENCHMARK_ALWAYS_INLINE
operator double&() {
return value; }
683 Counter::Flags
inline operator|(
const Counter::Flags& LHS,
684 const Counter::Flags& RHS) {
685 return static_cast<Counter::Flags
>(
static_cast<int>(LHS) |
686 static_cast<int>(RHS));
690 typedef std::map<std::string, Counter> UserCounters;
696 enum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLambda };
698 typedef int64_t ComplexityN;
700 typedef int64_t IterationCount;
702 enum StatisticUnit { kTime, kPercentage };
706 typedef double(BigOFunc)(ComplexityN);
710 typedef double(StatisticsFunc)(
const std::vector<double>&);
715 StatisticsFunc* compute_;
718 Statistics(
const std::string& name, StatisticsFunc* compute,
719 StatisticUnit unit = kTime)
720 : name_(name), compute_(compute), unit_(unit) {}
728 enum AggregationReportMode
729 #if defined(BENCHMARK_HAS_CXX11)
738 ARM_Default = 1U << 0U,
740 ARM_FileReportAggregatesOnly = 1U << 1U,
742 ARM_DisplayReportAggregatesOnly = 1U << 2U,
744 ARM_ReportAggregatesOnly =
745 ARM_FileReportAggregatesOnly | ARM_DisplayReportAggregatesOnly
749 #if defined(BENCHMARK_HAS_CXX11)
780 inline bool KeepRunning();
792 inline bool KeepRunningBatch(IterationCount n);
841 void SkipWithMessage(
const std::string& msg);
862 void SkipWithError(
const std::string& msg);
865 bool skipped()
const {
return internal::NotSkipped != skipped_; }
868 bool error_occurred()
const {
return internal::SkippedWithError == skipped_; }
877 void SetIterationTime(
double seconds);
884 BENCHMARK_ALWAYS_INLINE
885 void SetBytesProcessed(int64_t bytes) {
886 counters[
"bytes_per_second"] =
887 Counter(
static_cast<double>(bytes), Counter::kIsRate, Counter::kIs1024);
890 BENCHMARK_ALWAYS_INLINE
891 int64_t bytes_processed()
const {
892 if (counters.find(
"bytes_per_second") != counters.end())
893 return static_cast<int64_t
>(counters.at(
"bytes_per_second"));
902 BENCHMARK_ALWAYS_INLINE
903 void SetComplexityN(ComplexityN complexity_n) {
904 complexity_n_ = complexity_n;
907 BENCHMARK_ALWAYS_INLINE
908 ComplexityN complexity_length_n()
const {
return complexity_n_; }
916 BENCHMARK_ALWAYS_INLINE
917 void SetItemsProcessed(int64_t items) {
918 counters[
"items_per_second"] =
919 Counter(
static_cast<double>(items), benchmark::Counter::kIsRate);
922 BENCHMARK_ALWAYS_INLINE
923 int64_t items_processed()
const {
924 if (counters.find(
"items_per_second") != counters.end())
925 return static_cast<int64_t
>(counters.at(
"items_per_second"));
941 void SetLabel(
const std::string& label);
944 BENCHMARK_ALWAYS_INLINE
945 int64_t range(std::size_t pos = 0)
const {
946 assert(range_.size() > pos);
950 BENCHMARK_DEPRECATED_MSG(
"use 'range(0)' instead")
951 int64_t range_x()
const {
return range(0); }
953 BENCHMARK_DEPRECATED_MSG(
"use 'range(1)' instead")
954 int64_t range_y()
const {
return range(1); }
957 BENCHMARK_ALWAYS_INLINE
958 int threads()
const {
return threads_; }
961 BENCHMARK_ALWAYS_INLINE
962 int thread_index()
const {
return thread_index_; }
964 BENCHMARK_ALWAYS_INLINE
965 IterationCount iterations()
const {
966 if (BENCHMARK_BUILTIN_EXPECT(!started_,
false)) {
969 return max_iterations - total_iterations_ + batch_leftover_;
972 BENCHMARK_ALWAYS_INLINE
973 std::string name()
const {
return name_; }
979 IterationCount total_iterations_;
984 IterationCount batch_leftover_;
987 const IterationCount max_iterations;
992 internal::Skipped skipped_;
995 std::vector<int64_t> range_;
997 ComplexityN complexity_n_;
1001 UserCounters counters;
1004 State(std::string name, IterationCount max_iters,
1005 const std::vector<int64_t>& ranges,
int thread_i,
int n_threads,
1009 void StartKeepRunning();
1012 inline bool KeepRunningInternal(IterationCount n,
bool is_batch);
1013 void FinishKeepRunning();
1015 const std::string name_;
1016 const int thread_index_;
1026 inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunning() {
1027 return KeepRunningInternal(1,
false);
1030 inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunningBatch(IterationCount n) {
1031 return KeepRunningInternal(n,
true);
1034 inline BENCHMARK_ALWAYS_INLINE
bool State::KeepRunningInternal(IterationCount n,
1040 assert(is_batch || n == 1);
1041 if (BENCHMARK_BUILTIN_EXPECT(total_iterations_ >= n,
true)) {
1042 total_iterations_ -= n;
1047 if (!skipped() && total_iterations_ >= n) {
1048 total_iterations_ -= n;
1053 if (is_batch && total_iterations_ != 0) {
1054 batch_leftover_ = n - total_iterations_;
1055 total_iterations_ = 0;
1058 FinishKeepRunning();
1064 typedef std::forward_iterator_tag iterator_category;
1068 typedef std::ptrdiff_t difference_type;
1072 BENCHMARK_ALWAYS_INLINE
1075 BENCHMARK_ALWAYS_INLINE
1077 : cached_(st->skipped() ? 0 : st->max_iterations), parent_(st) {}
1080 BENCHMARK_ALWAYS_INLINE
1081 Value operator*()
const {
return Value(); }
1083 BENCHMARK_ALWAYS_INLINE
1084 StateIterator& operator++() {
1085 assert(cached_ > 0);
1090 BENCHMARK_ALWAYS_INLINE
1091 bool operator!=(StateIterator
const&)
const {
1092 if (BENCHMARK_BUILTIN_EXPECT(cached_ != 0,
true))
return true;
1093 parent_->FinishKeepRunning();
1098 IterationCount cached_;
1099 State*
const parent_;
1102 inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::begin() {
1103 return StateIterator(
this);
1105 inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::end() {
1107 return StateIterator();
1110 namespace internal {
1112 typedef void(Function)(State&);
1128 Benchmark* Name(
const std::string& name);
1141 Benchmark* Range(int64_t start, int64_t limit);
1146 Benchmark* DenseRange(int64_t start, int64_t limit,
int step = 1);
1151 Benchmark* Args(
const std::vector<int64_t>& args);
1156 Benchmark* ArgPair(int64_t x, int64_t y) {
1157 std::vector<int64_t> args;
1166 Benchmark* Ranges(
const std::vector<std::pair<int64_t, int64_t> >& ranges);
1171 Benchmark* ArgsProduct(
const std::vector<std::vector<int64_t> >& arglists);
1174 Benchmark* ArgName(
const std::string& name);
1178 Benchmark* ArgNames(
const std::vector<std::string>& names);
1183 Benchmark* RangePair(int64_t lo1, int64_t hi1, int64_t lo2, int64_t hi2) {
1184 std::vector<std::pair<int64_t, int64_t> > ranges;
1185 ranges.push_back(std::make_pair(lo1, hi1));
1186 ranges.push_back(std::make_pair(lo2, hi2));
1187 return Ranges(ranges);
1214 Benchmark* RangeMultiplier(
int multiplier);
1234 Benchmark* Iterations(IterationCount n);
1245 Benchmark* ReportAggregatesOnly(
bool value =
true);
1248 Benchmark* DisplayAggregatesOnly(
bool value =
true);
1275 Benchmark* Complexity(BigO complexity = benchmark::oAuto);
1279 Benchmark* Complexity(BigOFunc* complexity);
1282 Benchmark* ComputeStatistics(
const std::string& name,
1283 StatisticsFunc* statistics,
1284 StatisticUnit unit = kTime);
1305 Benchmark* ThreadRange(
int min_threads,
int max_threads);
1311 Benchmark* DenseThreadRange(
int min_threads,
int max_threads,
int stride = 1);
1316 virtual void Run(
State& state) = 0;
1318 TimeUnit GetTimeUnit()
const;
1321 explicit Benchmark(
const std::string& name);
1322 void SetName(
const std::string& name);
1325 const char* GetName()
const;
1326 int ArgsCnt()
const;
1327 const char* GetArgName(
int arg)
const;
1334 AggregationReportMode aggregation_report_mode_;
1335 std::vector<std::string> arg_names_;
1336 std::vector<std::vector<int64_t> > args_;
1338 TimeUnit time_unit_;
1339 bool use_default_time_unit_;
1341 int range_multiplier_;
1343 double min_warmup_time_;
1344 IterationCount iterations_;
1346 bool measure_process_cpu_time_;
1347 bool use_real_time_;
1348 bool use_manual_time_;
1350 BigOFunc* complexity_lambda_;
1351 std::vector<Statistics> statistics_;
1352 std::vector<int> thread_counts_;
1355 callback_function setup_;
1356 callback_function teardown_;
1359 #if defined(BENCHMARK_HAS_CXX11)
1365 #if defined(BENCHMARK_HAS_CXX11)
1378 internal::Function* fn);
1380 #if defined(BENCHMARK_HAS_CXX11)
1381 template <
class Lambda>
1387 BENCHMARK_EXPORT
void ClearRegisteredBenchmarks();
1389 namespace internal {
1397 void Run(
State& st) BENCHMARK_OVERRIDE;
1403 #ifdef BENCHMARK_HAS_CXX11
1404 template <
class Lambda>
1405 class LambdaBenchmark :
public Benchmark {
1407 void Run(
State& st) BENCHMARK_OVERRIDE { lambda_(st); }
1410 template <
class OLambda>
1411 LambdaBenchmark(
const std::string& name, OLambda&& lam)
1412 : Benchmark(name), lambda_(std::forward<OLambda>(lam)) {}
1414 LambdaBenchmark(LambdaBenchmark
const&) =
delete;
1416 template <
class Lam>
1417 friend Benchmark* ::benchmark::RegisterBenchmark(
const std::string&, Lam&&);
1424 inline internal::Benchmark* RegisterBenchmark(
const std::string& name,
1425 internal::Function* fn) {
1428 return internal::RegisterBenchmarkInternal(
1429 ::
new internal::FunctionBenchmark(name, fn));
1432 #ifdef BENCHMARK_HAS_CXX11
1433 template <
class Lambda>
1434 internal::Benchmark* RegisterBenchmark(
const std::string& name, Lambda&& fn) {
1436 internal::LambdaBenchmark<typename std::decay<Lambda>::type>;
1439 return internal::RegisterBenchmarkInternal(
1440 ::
new BenchType(name, std::forward<Lambda>(fn)));
1444 #if defined(BENCHMARK_HAS_CXX11) && \
1445 (!defined(BENCHMARK_GCC_VERSION) || BENCHMARK_GCC_VERSION >= 409)
1446 template <
class Lambda,
class... Args>
1447 internal::Benchmark* RegisterBenchmark(
const std::string& name, Lambda&& fn,
1449 return benchmark::RegisterBenchmark(
1453 #define BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK
1461 void Run(
State& st) BENCHMARK_OVERRIDE {
1463 this->BenchmarkCase(st);
1468 virtual void SetUp(
const State&) {}
1469 virtual void TearDown(
const State&) {}
1471 virtual void SetUp(
State& st) { SetUp(
const_cast<const State&
>(st)); }
1472 virtual void TearDown(
State& st) { TearDown(
const_cast<const State&
>(st)); }
1475 virtual void BenchmarkCase(
State&) = 0;
1485 #if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0)
1486 #define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__
1488 #define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__
1492 #ifdef BENCHMARK_HAS_CXX11
1493 #define BENCHMARK_PRIVATE_NAME(...) \
1494 BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, \
1497 #define BENCHMARK_PRIVATE_NAME(n) \
1498 BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, n)
1501 #define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c)
1502 #define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c
1504 #define BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method) \
1505 BaseClass##_##Method##_Benchmark
1507 #define BENCHMARK_PRIVATE_DECLARE(n) \
1508 static ::benchmark::internal::Benchmark* BENCHMARK_PRIVATE_NAME(n) \
1511 #ifdef BENCHMARK_HAS_CXX11
1512 #define BENCHMARK(...) \
1513 BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
1514 (::benchmark::internal::RegisterBenchmarkInternal( \
1515 new ::benchmark::internal::FunctionBenchmark(#__VA_ARGS__, \
1518 #define BENCHMARK(n) \
1519 BENCHMARK_PRIVATE_DECLARE(n) = \
1520 (::benchmark::internal::RegisterBenchmarkInternal( \
1521 new ::benchmark::internal::FunctionBenchmark(#n, n)))
1525 #define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a))
1526 #define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->Args({(a1), (a2)})
1527 #define BENCHMARK_WITH_UNIT(n, t) BENCHMARK(n)->Unit((t))
1528 #define BENCHMARK_RANGE(n, lo, hi) BENCHMARK(n)->Range((lo), (hi))
1529 #define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \
1530 BENCHMARK(n)->RangePair({{(l1), (h1)}, {(l2), (h2)}})
1532 #ifdef BENCHMARK_HAS_CXX11
1545 #define BENCHMARK_CAPTURE(func, test_case_name, ...) \
1546 BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
1547 (::benchmark::internal::RegisterBenchmarkInternal( \
1548 new ::benchmark::internal::FunctionBenchmark( \
1549 #func "/" #test_case_name, \
1550 [](::benchmark::State& st) { func(st, __VA_ARGS__); })))
1562 #define BENCHMARK_TEMPLATE1(n, a) \
1563 BENCHMARK_PRIVATE_DECLARE(n) = \
1564 (::benchmark::internal::RegisterBenchmarkInternal( \
1565 new ::benchmark::internal::FunctionBenchmark(#n "<" #a ">", n<a>)))
1567 #define BENCHMARK_TEMPLATE2(n, a, b) \
1568 BENCHMARK_PRIVATE_DECLARE(n) = \
1569 (::benchmark::internal::RegisterBenchmarkInternal( \
1570 new ::benchmark::internal::FunctionBenchmark(#n "<" #a "," #b ">", \
1573 #ifdef BENCHMARK_HAS_CXX11
1574 #define BENCHMARK_TEMPLATE(n, ...) \
1575 BENCHMARK_PRIVATE_DECLARE(n) = \
1576 (::benchmark::internal::RegisterBenchmarkInternal( \
1577 new ::benchmark::internal::FunctionBenchmark( \
1578 #n "<" #__VA_ARGS__ ">", n<__VA_ARGS__>)))
1580 #define BENCHMARK_TEMPLATE(n, a) BENCHMARK_TEMPLATE1(n, a)
1583 #ifdef BENCHMARK_HAS_CXX11
1596 #define BENCHMARK_TEMPLATE1_CAPTURE(func, a, test_case_name, ...) \
1597 BENCHMARK_CAPTURE(func<a>, test_case_name, __VA_ARGS__)
1599 #define BENCHMARK_TEMPLATE2_CAPTURE(func, a, b, test_case_name, ...) \
1600 BENCHMARK_PRIVATE_DECLARE(func) = \
1601 (::benchmark::internal::RegisterBenchmarkInternal( \
1602 new ::benchmark::internal::FunctionBenchmark( \
1603 #func "<" #a "," #b ">" \
1604 "/" #test_case_name, \
1605 [](::benchmark::State& st) { func<a, b>(st, __VA_ARGS__); })))
1608 #define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1609 class BaseClass##_##Method##_Benchmark : public BaseClass { \
1611 BaseClass##_##Method##_Benchmark() { \
1612 this->SetName(#BaseClass "/" #Method); \
1616 void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \
1619 #define BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1620 class BaseClass##_##Method##_Benchmark : public BaseClass<a> { \
1622 BaseClass##_##Method##_Benchmark() { \
1623 this->SetName(#BaseClass "<" #a ">/" #Method); \
1627 void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \
1630 #define BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1631 class BaseClass##_##Method##_Benchmark : public BaseClass<a, b> { \
1633 BaseClass##_##Method##_Benchmark() { \
1634 this->SetName(#BaseClass "<" #a "," #b ">/" #Method); \
1638 void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \
1641 #ifdef BENCHMARK_HAS_CXX11
1642 #define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, ...) \
1643 class BaseClass##_##Method##_Benchmark : public BaseClass<__VA_ARGS__> { \
1645 BaseClass##_##Method##_Benchmark() { \
1646 this->SetName(#BaseClass "<" #__VA_ARGS__ ">/" #Method); \
1650 void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \
1653 #define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(n, a) \
1654 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(n, a)
1657 #define BENCHMARK_DEFINE_F(BaseClass, Method) \
1658 BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1659 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1661 #define BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a) \
1662 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1663 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1665 #define BENCHMARK_TEMPLATE2_DEFINE_F(BaseClass, Method, a, b) \
1666 BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1667 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1669 #ifdef BENCHMARK_HAS_CXX11
1670 #define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, ...) \
1671 BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \
1672 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1674 #define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, a) \
1675 BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a)
1678 #define BENCHMARK_REGISTER_F(BaseClass, Method) \
1679 BENCHMARK_PRIVATE_REGISTER_F(BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method))
1681 #define BENCHMARK_PRIVATE_REGISTER_F(TestName) \
1682 BENCHMARK_PRIVATE_DECLARE(TestName) = \
1683 (::benchmark::internal::RegisterBenchmarkInternal(new TestName()))
1686 #define BENCHMARK_F(BaseClass, Method) \
1687 BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
1688 BENCHMARK_REGISTER_F(BaseClass, Method); \
1689 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1691 #define BENCHMARK_TEMPLATE1_F(BaseClass, Method, a) \
1692 BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
1693 BENCHMARK_REGISTER_F(BaseClass, Method); \
1694 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1696 #define BENCHMARK_TEMPLATE2_F(BaseClass, Method, a, b) \
1697 BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
1698 BENCHMARK_REGISTER_F(BaseClass, Method); \
1699 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1701 #ifdef BENCHMARK_HAS_CXX11
1702 #define BENCHMARK_TEMPLATE_F(BaseClass, Method, ...) \
1703 BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \
1704 BENCHMARK_REGISTER_F(BaseClass, Method); \
1705 void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
1707 #define BENCHMARK_TEMPLATE_F(BaseClass, Method, a) \
1708 BENCHMARK_TEMPLATE1_F(BaseClass, Method, a)
1713 #define BENCHMARK_MAIN() \
1714 int main(int argc, char** argv) { \
1715 char arg0_default[] = "benchmark"; \
1716 char* args_default = arg0_default; \
1719 argv = &args_default; \
1721 ::benchmark::Initialize(&argc, argv); \
1722 if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; \
1723 ::benchmark::RunSpecifiedBenchmarks(); \
1724 ::benchmark::Shutdown(); \
1727 int main(int, char**)
1732 namespace benchmark {
1742 enum Scaling { UNKNOWN, ENABLED, DISABLED };
1746 double cycles_per_second;
1747 std::vector<CacheInfo> caches;
1748 std::vector<double> load_avg;
1754 BENCHMARK_DISALLOW_COPY_AND_ASSIGN(
CPUInfo);
1764 BENCHMARK_DISALLOW_COPY_AND_ASSIGN(
SystemInfo);
1771 std::string function_name;
1773 std::string min_time;
1774 std::string min_warmup_time;
1775 std::string iterations;
1776 std::string repetitions;
1777 std::string time_type;
1778 std::string threads;
1782 std::string str()
const;
1796 size_t name_field_width;
1797 static const char* executable_name;
1802 static const int64_t no_repetition_index = -1;
1803 enum RunType { RT_Iteration, RT_Aggregate };
1806 : run_type(RT_Iteration),
1807 aggregate_unit(kTime),
1808 skipped(internal::NotSkipped),
1811 time_unit(GetDefaultTimeUnit()),
1812 real_accumulated_time(0),
1813 cpu_accumulated_time(0),
1814 max_heapbytes_used(0),
1815 use_real_time_for_initial_big_o(
false),
1817 complexity_lambda(),
1819 report_big_o(
false),
1821 memory_result(NULL),
1822 allocs_per_iter(0.0) {}
1824 std::string benchmark_name()
const;
1826 int64_t family_index;
1827 int64_t per_family_instance_index;
1829 std::string aggregate_name;
1830 StatisticUnit aggregate_unit;
1831 std::string report_label;
1832 internal::Skipped skipped;
1833 std::string skip_message;
1835 IterationCount iterations;
1837 int64_t repetition_index;
1838 int64_t repetitions;
1840 double real_accumulated_time;
1841 double cpu_accumulated_time;
1847 double GetAdjustedRealTime()
const;
1853 double GetAdjustedCPUTime()
const;
1856 double max_heapbytes_used;
1860 bool use_real_time_for_initial_big_o;
1864 BigOFunc* complexity_lambda;
1865 ComplexityN complexity_n;
1868 const std::vector<internal::Statistics>* statistics;
1874 UserCounters counters;
1878 double allocs_per_iter;
1891 std::vector<BenchmarkReporter::Run> Runs;
1904 virtual bool ReportContext(
const Context& context) = 0;
1908 virtual void ReportRunsConfig(
double ,
1919 virtual void ReportRuns(
const std::vector<Run>& report) = 0;
1923 virtual void Finalize() {}
1927 void SetOutputStream(std::ostream* out) {
1929 output_stream_ = out;
1934 void SetErrorStream(std::ostream* err) {
1936 error_stream_ = err;
1939 std::ostream& GetOutputStream()
const {
return *output_stream_; }
1941 std::ostream& GetErrorStream()
const {
return *error_stream_; }
1943 virtual ~BenchmarkReporter();
1948 static void PrintBasicContext(std::ostream* out, Context
const& context);
1951 std::ostream* output_stream_;
1952 std::ostream* error_stream_;
1959 enum OutputOptions {
1963 OO_ColorTabular = OO_Color | OO_Tabular,
1964 OO_Defaults = OO_ColorTabular
1967 : output_options_(opts_), name_field_width_(0), printed_header_(
false) {}
1969 bool ReportContext(
const Context& context) BENCHMARK_OVERRIDE;
1970 void ReportRuns(
const std::vector<Run>& reports) BENCHMARK_OVERRIDE;
1973 virtual void PrintRunData(
const Run& report);
1974 virtual void PrintHeader(
const Run& report);
1976 OutputOptions output_options_;
1977 size_t name_field_width_;
1978 UserCounters prev_counters_;
1979 bool printed_header_;
1985 bool ReportContext(
const Context& context) BENCHMARK_OVERRIDE;
1986 void ReportRuns(
const std::vector<Run>& reports) BENCHMARK_OVERRIDE;
1987 void Finalize() BENCHMARK_OVERRIDE;
1990 void PrintRunData(
const Run& report);
1995 class BENCHMARK_EXPORT BENCHMARK_DEPRECATED_MSG(
1996 "The CSV Reporter will be removed in a future release") CSVReporter
1999 CSVReporter() : printed_header_(false) {}
2000 bool ReportContext(
const Context& context) BENCHMARK_OVERRIDE;
2001 void ReportRuns(
const std::vector<Run>& reports) BENCHMARK_OVERRIDE;
2004 void PrintRunData(
const Run& report);
2006 bool printed_header_;
2007 std::set<std::string> user_counter_names_;
2010 inline const char* GetTimeUnitString(TimeUnit unit) {
2021 BENCHMARK_UNREACHABLE();
2024 inline double GetTimeUnitMultiplier(TimeUnit unit) {
2035 BENCHMARK_UNREACHABLE();
2048 std::vector<int64_t> CreateRange(int64_t lo, int64_t hi,
int multi);
2052 std::vector<int64_t> CreateDenseRange(int64_t start, int64_t limit,
int step);
2056 #if defined(_MSC_VER)
2057 #pragma warning(pop)
Definition: benchmark.h:1790
Definition: benchmark.h:1957
Definition: benchmark.h:633
Definition: benchmark.h:1457
Definition: benchmark.h:1982
Definition: benchmark.h:378
Definition: benchmark.h:422
Definition: benchmark.h:762
Definition: benchmark_register.cc:73
Definition: benchmark_api_internal.h:18
Definition: benchmark.h:1120
Definition: benchmark.h:1392
Definition: perf_counters.h:149
Definition: thread_manager.h:12
Definition: thread_timer.h:10
Definition: benchmark.h:1770
Definition: benchmark.h:1792
Definition: benchmark.h:1881
Definition: benchmark.h:1801
Definition: benchmark.h:1735
Definition: benchmark.h:1734
Definition: benchmark.h:382
Definition: benchmark.h:1063
Definition: benchmark.h:1062
Definition: benchmark.h:1758
Definition: benchmark.h:713