chore: import upstream snapshot with attribution
bazel / bazel.ubuntu-latest (push) Failing after 1s
build-and-test-perfcounters / ubuntu-latest.Debug (push) Failing after 0s
build-and-test-perfcounters / ubuntu-latest.Release (push) Failing after 1s
doxygen / Build HTML documentation (push) Failing after 1s
python + Bazel pre-commit checks / pre-commit (push) Failing after 1s
sanitizer / tsan.Debug (push) Failing after 1s
sanitizer / ubsan.Debug (push) Failing after 0s
sanitizer / ubsan.RelWithDebInfo (push) Failing after 1s
build-and-test-min-cmake / ubuntu-latest.min-cmake (push) Failing after 1s
clang-format-lint / check-clang-format (push) Failing after 1s
sanitizer / asan.Debug (push) Failing after 1s
sanitizer / msan.RelWithDebInfo (push) Failing after 1s
clang-tidy / run-clang-tidy (push) Failing after 1s
sanitizer / msan.Debug (push) Failing after 1s
sanitizer / asan.RelWithDebInfo (push) Failing after 0s
sanitizer / tsan.RelWithDebInfo (push) Failing after 0s
test-bindings / Test Rust bindings on ubuntu-latest (push) Failing after 0s
test-bindings / Test Python 3.10 bindings on ubuntu-latest (push) Failing after 0s
test-bindings / Test Python 3.11 bindings on ubuntu-latest (push) Failing after 0s
test-bindings / Test Python 3.12 bindings on ubuntu-latest (push) Failing after 1s
test-bindings / Test Python 3.13 bindings on ubuntu-latest (push) Failing after 0s
build-and-test / macos-latest.Debug.shared.clang++ (push) Has been cancelled
build-and-test / ubuntu-22.04.Debug.shared.clang++ (push) Has been cancelled
build-and-test / ubuntu-24.04.Debug.shared.clang++ (push) Has been cancelled
build-and-test / ubuntu-24.04-arm.Debug.shared.clang++ (push) Has been cancelled
bazel / bazel.macos-latest (push) Has been cancelled
bazel / bazel.windows-latest (push) Has been cancelled
build-and-test-min-cmake / macos-latest.min-cmake (push) Has been cancelled
build-and-test / ubuntu-22.04.Debug.static.clang++ (push) Has been cancelled
build-and-test / macos-latest.Debug.shared.g++ (push) Has been cancelled
build-and-test / ubuntu-22.04.Debug.shared.g++ (push) Has been cancelled
build-and-test / ubuntu-24.04.Debug.shared.g++ (push) Has been cancelled
build-and-test / ubuntu-24.04-arm.Debug.shared.g++ (push) Has been cancelled
build-and-test / macos-latest.Debug.static.g++ (push) Has been cancelled
build-and-test / ubuntu-22.04.Debug.static.g++ (push) Has been cancelled
build-and-test / ubuntu-24.04.Debug.static.g++ (push) Has been cancelled
build-and-test / ubuntu-24.04-arm.Debug.static.g++ (push) Has been cancelled
build-and-test / macos-latest.Release.shared.clang++ (push) Has been cancelled
build-and-test / ubuntu-22.04.Release.shared.clang++ (push) Has been cancelled
build-and-test / ubuntu-24.04.Release.shared.clang++ (push) Has been cancelled
build-and-test / ubuntu-24.04-arm.Release.shared.clang++ (push) Has been cancelled
build-and-test / macos-latest.Release.static.clang++ (push) Has been cancelled
build-and-test / ubuntu-22.04.Release.static.clang++ (push) Has been cancelled
build-and-test / macos-latest.Debug.static.clang++ (push) Has been cancelled
build-and-test / ubuntu-24.04.Debug.static.clang++ (push) Has been cancelled
build-and-test / ubuntu-24.04-arm.Debug.static.clang++ (push) Has been cancelled
build-and-test / macos-latest.Release.static.g++ (push) Has been cancelled
build-and-test / ubuntu-22.04.Release.static.g++ (push) Has been cancelled
build-and-test / windows-2025.Debug.static.VS-18-2025 (push) Has been cancelled
build-and-test / windows-2022.Release.shared.VS-17-2022 (push) Has been cancelled
build-and-test / windows-2022.Release.static.VS-17-2022 (push) Has been cancelled
build-and-test / windows-2025.Release.shared.VS-18-2025 (push) Has been cancelled
build-and-test / windows-2025.Release.static.VS-18-2025 (push) Has been cancelled
build-and-test / windows-latest.Debug.shared.CLANG64 (push) Has been cancelled
build-and-test / windows-latest.Debug.shared.MINGW64 (push) Has been cancelled
build-and-test / windows-latest.Debug.shared.UCRT64 (push) Has been cancelled
build-and-test / windows-latest.Debug.static.CLANG64 (push) Has been cancelled
build-and-test / windows-latest.Debug.static.MINGW64 (push) Has been cancelled
build-and-test / windows-latest.Debug.static.UCRT64 (push) Has been cancelled
build-and-test / ubuntu-24.04.Release.static.clang++ (push) Has been cancelled
build-and-test / ubuntu-24.04-arm.Release.static.clang++ (push) Has been cancelled
build-and-test / macos-latest.Release.shared.g++ (push) Has been cancelled
build-and-test / ubuntu-22.04.Release.shared.g++ (push) Has been cancelled
build-and-test / ubuntu-24.04.Release.shared.g++ (push) Has been cancelled
build-and-test / ubuntu-24.04-arm.Release.shared.g++ (push) Has been cancelled
build-and-test / ubuntu-24.04.Release.static.g++ (push) Has been cancelled
build-and-test / ubuntu-24.04-arm.Release.static.g++ (push) Has been cancelled
build-and-test / windows-2022.Debug.shared.VS-17-2022 (push) Has been cancelled
build-and-test / windows-2022.Debug.static.VS-17-2022 (push) Has been cancelled
build-and-test / windows-2025.Debug.shared.VS-18-2025 (push) Has been cancelled
build-and-test / windows-latest.Release.static.MINGW64 (push) Has been cancelled
build-and-test / windows-latest.Release.static.UCRT64 (push) Has been cancelled
test-bindings / Test Python 3.10 bindings on macos-latest (push) Has been cancelled
test-bindings / Test Python 3.11 bindings on macos-latest (push) Has been cancelled
test-bindings / Test Python 3.12 bindings on macos-latest (push) Has been cancelled
test-bindings / Test Python 3.13 bindings on macos-latest (push) Has been cancelled
build-and-test / windows-latest.Release.shared.CLANG64 (push) Has been cancelled
build-and-test / windows-latest.Release.shared.MINGW64 (push) Has been cancelled
build-and-test / windows-latest.Release.shared.UCRT64 (push) Has been cancelled
build-and-test / windows-latest.Release.static.CLANG64 (push) Has been cancelled
test-bindings / Test Python 3.12 bindings on windows-latest (push) Has been cancelled
test-bindings / Test Python 3.13 bindings on windows-latest (push) Has been cancelled
test-bindings / Test Python 3.10 bindings on windows-latest (push) Has been cancelled
test-bindings / Test Python 3.11 bindings on windows-latest (push) Has been cancelled
test-bindings / Test Rust bindings on macos-latest (push) Has been cancelled
test-bindings / Test Rust bindings on windows-latest (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 12:28:34 +08:00
commit cb66c5d68e
221 changed files with 30725 additions and 0 deletions
+30
View File
@@ -0,0 +1,30 @@
// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BENCHMARK_BENCHMARK_H_
#define BENCHMARK_BENCHMARK_H_
#include "benchmark/benchmark_api.h"
#include "benchmark/counter.h"
#include "benchmark/macros.h"
#include "benchmark/managers.h"
#include "benchmark/registration.h"
#include "benchmark/reporter.h"
#include "benchmark/state.h"
#include "benchmark/statistics.h"
#include "benchmark/sysinfo.h"
#include "benchmark/types.h"
#include "benchmark/utils.h"
#endif // BENCHMARK_BENCHMARK_H_
+292
View File
@@ -0,0 +1,292 @@
// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BENCHMARK_BENCHMARK_API_H_
#define BENCHMARK_BENCHMARK_API_H_
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4251)
#endif
#include <functional>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "benchmark/counter.h"
#include "benchmark/macros.h"
#include "benchmark/state.h"
#include "benchmark/statistics.h"
#include "benchmark/types.h"
namespace benchmark {
const char kDefaultMinTimeStr[] = "0.5s";
BENCHMARK_EXPORT void MaybeReenterWithoutASLR(int, char**);
BENCHMARK_EXPORT std::string GetBenchmarkVersion();
BENCHMARK_EXPORT void PrintDefaultHelp();
BENCHMARK_EXPORT void Initialize(int* argc, char** argv,
void (*HelperPrintf)() = PrintDefaultHelp);
BENCHMARK_EXPORT void Shutdown();
BENCHMARK_EXPORT bool ReportUnrecognizedArguments(int argc, char** argv);
BENCHMARK_EXPORT std::string GetBenchmarkFilter();
BENCHMARK_EXPORT void SetBenchmarkFilter(std::string value);
BENCHMARK_EXPORT int32_t GetBenchmarkVerbosity();
BENCHMARK_EXPORT BenchmarkReporter* CreateDefaultDisplayReporter();
BENCHMARK_EXPORT size_t RunSpecifiedBenchmarks();
BENCHMARK_EXPORT size_t RunSpecifiedBenchmarks(std::string spec);
BENCHMARK_EXPORT size_t
RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter);
BENCHMARK_EXPORT size_t
RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, std::string spec);
BENCHMARK_EXPORT size_t RunSpecifiedBenchmarks(
BenchmarkReporter* display_reporter, BenchmarkReporter* file_reporter);
BENCHMARK_EXPORT size_t
RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
BenchmarkReporter* file_reporter, std::string spec);
BENCHMARK_EXPORT TimeUnit GetDefaultTimeUnit();
BENCHMARK_EXPORT void SetDefaultTimeUnit(TimeUnit unit);
BENCHMARK_EXPORT
void AddCustomContext(std::string key, std::string value);
struct ThreadRunnerBase {
virtual ~ThreadRunnerBase() {}
virtual void RunThreads(const std::function<void(int)>& fn) = 0;
};
using threadrunner_factory =
std::function<std::unique_ptr<ThreadRunnerBase>(int)>;
namespace internal {
class BenchmarkFamilies;
class BenchmarkInstance;
} // namespace internal
class BENCHMARK_EXPORT Benchmark {
public:
virtual ~Benchmark();
Benchmark* Name(const std::string& name);
Benchmark* Arg(int64_t x);
Benchmark* Unit(TimeUnit unit);
Benchmark* Range(int64_t start, int64_t limit);
Benchmark* DenseRange(int64_t start, int64_t limit, int step = 1);
Benchmark* Args(const std::vector<int64_t>& args);
Benchmark* ArgPair(int64_t x, int64_t y) {
std::vector<int64_t> args;
args.push_back(x);
args.push_back(y);
return Args(args);
}
Benchmark* Ranges(const std::vector<std::pair<int64_t, int64_t>>& ranges);
Benchmark* ArgsProduct(const std::vector<std::vector<int64_t>>& arglists);
Benchmark* ArgName(const std::string& name);
Benchmark* ArgNames(const std::vector<std::string>& names);
Benchmark* RangePair(int64_t lo1, int64_t hi1, int64_t lo2, int64_t hi2) {
std::vector<std::pair<int64_t, int64_t>> ranges;
ranges.push_back(std::make_pair(lo1, hi1));
ranges.push_back(std::make_pair(lo2, hi2));
return Ranges(ranges);
}
Benchmark* Setup(callback_function&&);
Benchmark* Setup(const callback_function&);
Benchmark* Teardown(callback_function&&);
Benchmark* Teardown(const callback_function&);
Benchmark* Apply(const std::function<void(Benchmark* benchmark)>&);
Benchmark* RangeMultiplier(int multiplier);
Benchmark* MinTime(double t);
Benchmark* MinWarmUpTime(double t);
Benchmark* Iterations(IterationCount n);
Benchmark* Repetitions(int n);
Benchmark* ReportAggregatesOnly(bool value = true);
Benchmark* DisplayAggregatesOnly(bool value = true);
Benchmark* MeasureProcessCPUTime();
Benchmark* UseRealTime();
Benchmark* UseManualTime();
Benchmark* Complexity(BigO complexity = benchmark::oAuto);
Benchmark* Complexity(BigOFunc* complexity);
Benchmark* ComputeStatistics(const std::string& name,
StatisticsFunc* statistics,
StatisticUnit unit = kTime);
Benchmark* Threads(int t);
Benchmark* ThreadRange(int min_threads, int max_threads);
Benchmark* DenseThreadRange(int min_threads, int max_threads, int stride = 1);
Benchmark* ThreadPerCpu();
Benchmark* ThreadRunner(threadrunner_factory&& factory);
virtual void Run(State& state) = 0;
TimeUnit GetTimeUnit() const;
protected:
explicit Benchmark(const std::string& name);
void SetName(const std::string& name);
public:
const char* GetName() const;
int ArgsCnt() const;
const char* GetArgName(int arg) const;
private:
friend class internal::BenchmarkFamilies;
friend class internal::BenchmarkInstance;
std::string name_;
internal::AggregationReportMode aggregation_report_mode_;
std::vector<std::string> arg_names_;
std::vector<std::vector<int64_t>> args_;
TimeUnit time_unit_;
bool use_default_time_unit_;
int range_multiplier_;
double min_time_;
double min_warmup_time_;
IterationCount iterations_;
int repetitions_;
bool measure_process_cpu_time_;
bool use_real_time_;
bool use_manual_time_;
BigO complexity_;
BigOFunc* complexity_lambda_;
std::vector<internal::Statistics> statistics_;
std::vector<int> thread_counts_;
callback_function setup_;
callback_function teardown_;
threadrunner_factory threadrunner_;
BENCHMARK_DISALLOW_COPY_AND_ASSIGN(Benchmark);
};
namespace internal {
typedef BENCHMARK_DEPRECATED_MSG(
"Use ::benchmark::Benchmark instead")::benchmark::Benchmark Benchmark;
typedef BENCHMARK_DEPRECATED_MSG(
"Use ::benchmark::threadrunner_factory instead")::benchmark::
threadrunner_factory threadrunner_factory;
typedef void(Function)(State&);
BENCHMARK_EXPORT ::benchmark::Benchmark* RegisterBenchmarkInternal(
std::unique_ptr<::benchmark::Benchmark>);
BENCHMARK_EXPORT std::map<std::string, std::string>*& GetGlobalContext();
BENCHMARK_EXPORT void UseCharPointer(char const volatile*);
BENCHMARK_EXPORT int InitializeStreams();
BENCHMARK_UNUSED static int stream_init_anchor = InitializeStreams();
} // namespace internal
Benchmark* RegisterBenchmark(const std::string& name, internal::Function* fn);
template <class Lambda>
Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn);
BENCHMARK_EXPORT void ClearRegisteredBenchmarks();
namespace internal {
class BENCHMARK_EXPORT FunctionBenchmark : public benchmark::Benchmark {
public:
FunctionBenchmark(const std::string& name, Function* func)
: Benchmark(name), func_(func) {}
void Run(State& st) override;
private:
Function* func_;
};
template <class Lambda>
class LambdaBenchmark : public benchmark::Benchmark {
public:
void Run(State& st) override { lambda_(st); }
template <class OLambda>
LambdaBenchmark(const std::string& name, OLambda&& lam)
: Benchmark(name), lambda_(std::forward<OLambda>(lam)) {}
private:
LambdaBenchmark(LambdaBenchmark const&) = delete;
Lambda lambda_;
};
} // namespace internal
inline Benchmark* RegisterBenchmark(const std::string& name,
internal::Function* fn) {
return internal::RegisterBenchmarkInternal(
::benchmark::internal::make_unique<internal::FunctionBenchmark>(name,
fn));
}
template <class Lambda>
Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn) {
using BenchType =
internal::LambdaBenchmark<typename std::decay<Lambda>::type>;
return internal::RegisterBenchmarkInternal(
::benchmark::internal::make_unique<BenchType>(name,
std::forward<Lambda>(fn)));
}
template <class Lambda, class... Args>
Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn,
Args&&... args) {
return benchmark::RegisterBenchmark(
name, [=](benchmark::State& st) { fn(st, args...); });
}
class Fixture : public Benchmark {
public:
Fixture() : Benchmark("") {}
void Run(State& st) override {
this->SetUp(st);
this->BenchmarkCase(st);
this->TearDown(st);
}
virtual void SetUp(const State&) {}
virtual void TearDown(const State&) {}
virtual void SetUp(State& st) { SetUp(const_cast<const State&>(st)); }
virtual void TearDown(State& st) { TearDown(const_cast<const State&>(st)); }
protected:
virtual void BenchmarkCase(State&) = 0;
};
BENCHMARK_EXPORT
std::vector<int64_t> CreateRange(int64_t lo, int64_t hi, int multi);
BENCHMARK_EXPORT
std::vector<int64_t> CreateDenseRange(int64_t start, int64_t limit, int step);
} // namespace benchmark
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#endif // BENCHMARK_BENCHMARK_API_H_
+80
View File
@@ -0,0 +1,80 @@
// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BENCHMARK_COUNTER_H_
#define BENCHMARK_COUNTER_H_
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4251)
#endif
#include <map>
#include <string>
#include "benchmark/macros.h"
#include "benchmark/types.h"
namespace benchmark {
class BENCHMARK_EXPORT Counter {
public:
enum Flags {
kDefaults = 0,
kIsRate = 1 << 0,
kAvgThreads = 1 << 1,
kAvgThreadsRate = kIsRate | kAvgThreads,
kIsIterationInvariant = 1 << 2,
kIsIterationInvariantRate = kIsRate | kIsIterationInvariant,
kAvgIterations = 1 << 3,
kAvgIterationsRate = kIsRate | kAvgIterations,
kInvert = 1 << 31
};
enum OneK { kIs1000 = 1000, kIs1024 = 1024 };
double value;
Flags flags;
OneK oneK;
BENCHMARK_ALWAYS_INLINE
Counter(double v = 0., Flags f = kDefaults, OneK k = kIs1000)
: value(v), flags(f), oneK(k) {}
BENCHMARK_ALWAYS_INLINE operator double const&() const { return value; }
BENCHMARK_ALWAYS_INLINE operator double&() { return value; }
};
Counter::Flags inline operator|(const Counter::Flags& LHS,
const Counter::Flags& RHS) {
return static_cast<Counter::Flags>(static_cast<int>(LHS) |
static_cast<int>(RHS));
}
using UserCounters = std::map<std::string, Counter>;
namespace internal {
void Finish(UserCounters* l, IterationCount iterations, double cpu_time,
double num_threads);
void Increment(UserCounters* l, UserCounters const& r);
bool SameNames(UserCounters const& l, UserCounters const& r);
} // namespace internal
} // namespace benchmark
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#endif // BENCHMARK_COUNTER_H_
+47
View File
@@ -0,0 +1,47 @@
#ifndef BENCHMARK_EXPORT_H
#define BENCHMARK_EXPORT_H
#if defined(_WIN32)
#define EXPORT_ATTR __declspec(dllexport)
#define IMPORT_ATTR __declspec(dllimport)
#define NO_EXPORT_ATTR
#define DEPRECATED_ATTR __declspec(deprecated)
#else // _WIN32
#define EXPORT_ATTR __attribute__((visibility("default")))
#define IMPORT_ATTR __attribute__((visibility("default")))
#define NO_EXPORT_ATTR __attribute__((visibility("hidden")))
#define DEPRECATE_ATTR __attribute__((__deprecated__))
#endif // _WIN32
#ifdef BENCHMARK_STATIC_DEFINE
#define BENCHMARK_EXPORT
#define BENCHMARK_NO_EXPORT
#else // BENCHMARK_STATIC_DEFINE
#ifndef BENCHMARK_EXPORT
#ifdef benchmark_EXPORTS
/* We are building this library */
#define BENCHMARK_EXPORT EXPORT_ATTR
#else // benchmark_EXPORTS
/* We are using this library */
#define BENCHMARK_EXPORT IMPORT_ATTR
#endif // benchmark_EXPORTS
#endif // !BENCHMARK_EXPORT
#ifndef BENCHMARK_NO_EXPORT
#define BENCHMARK_NO_EXPORT NO_EXPORT_ATTR
#endif // !BENCHMARK_NO_EXPORT
#endif // BENCHMARK_STATIC_DEFINE
#ifndef BENCHMARK_DEPRECATED
#define BENCHMARK_DEPRECATED DEPRECATE_ATTR
#endif // BENCHMARK_DEPRECATED
#ifndef BENCHMARK_DEPRECATED_EXPORT
#define BENCHMARK_DEPRECATED_EXPORT BENCHMARK_EXPORT BENCHMARK_DEPRECATED
#endif // BENCHMARK_DEPRECATED_EXPORT
#ifndef BENCHMARK_DEPRECATED_NO_EXPORT
#define BENCHMARK_DEPRECATED_NO_EXPORT BENCHMARK_NO_EXPORT BENCHMARK_DEPRECATED
#endif // BENCHMARK_DEPRECATED_EXPORT
#endif /* BENCHMARK_EXPORT_H */
+136
View File
@@ -0,0 +1,136 @@
// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BENCHMARK_MACROS_H_
#define BENCHMARK_MACROS_H_
#if defined(_MSC_VER)
#include <intrin.h>
#endif
#include <stdint.h>
#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&) = delete; \
TypeName& operator=(const TypeName&) = delete
#ifdef BENCHMARK_HAS_CXX17
#define BENCHMARK_UNUSED [[maybe_unused]]
#elif defined(__GNUC__) || defined(__clang__)
#define BENCHMARK_UNUSED __attribute__((unused))
#else
#define BENCHMARK_UNUSED
#endif
#if defined(__clang__)
#define BENCHMARK_DONT_OPTIMIZE __attribute__((optnone))
#elif defined(__GNUC__) || defined(__GNUG__)
#define BENCHMARK_DONT_OPTIMIZE __attribute__((optimize(0)))
#else
#define BENCHMARK_DONT_OPTIMIZE
#endif
#if defined(__GNUC__) || defined(__clang__)
#define BENCHMARK_ALWAYS_INLINE __attribute__((always_inline))
#elif defined(_MSC_VER) && !defined(__clang__)
#define BENCHMARK_ALWAYS_INLINE __forceinline
#define __func__ __FUNCTION__
#else
#define BENCHMARK_ALWAYS_INLINE
#endif
#define BENCHMARK_INTERNAL_TOSTRING2(x) #x
#define BENCHMARK_INTERNAL_TOSTRING(x) BENCHMARK_INTERNAL_TOSTRING2(x)
#if (defined(__GNUC__) && !defined(__NVCC__) && !defined(__NVCOMPILER)) || \
defined(__clang__)
#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)
#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma("GCC diagnostic pop")
#elif defined(__NVCOMPILER)
#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)
#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
_Pragma("diagnostic push") \
_Pragma("diag_suppress deprecated_entity_with_custom_message")
#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma("diagnostic pop")
#elif defined(_MSC_VER)
#define BENCHMARK_BUILTIN_EXPECT(x, y) x
#define BENCHMARK_DEPRECATED_MSG(msg) __declspec(deprecated(msg))
#define BENCHMARK_WARNING_MSG(msg) \
__pragma(message(__FILE__ "(" BENCHMARK_INTERNAL_TOSTRING( \
__LINE__) ") : warning note: " msg))
#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
__pragma(warning(push)) __pragma(warning(disable : 4996))
#define BENCHMARK_RESTORE_DEPRECATED_WARNING __pragma(warning(pop))
#else
#define BENCHMARK_BUILTIN_EXPECT(x, y) x
#define BENCHMARK_DEPRECATED_MSG(msg)
#define BENCHMARK_WARNING_MSG(msg) \
__pragma(message(__FILE__ "(" BENCHMARK_INTERNAL_TOSTRING( \
__LINE__) ") : warning note: " msg))
#define BENCHMARK_DISABLE_DEPRECATED_WARNING
#define BENCHMARK_RESTORE_DEPRECATED_WARNING
#endif
#if defined(__GNUC__) && !defined(__clang__)
#define BENCHMARK_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
#endif
#ifndef __has_builtin
#define __has_builtin(x) 0
#endif
#if defined(__GNUC__) || __has_builtin(__builtin_unreachable)
#define BENCHMARK_UNREACHABLE() __builtin_unreachable()
#elif defined(_MSC_VER)
#define BENCHMARK_UNREACHABLE() __assume(false)
#else
#define BENCHMARK_UNREACHABLE() ((void)0)
#endif
#if defined(__GNUC__)
#if defined(__i386__) || defined(__x86_64__)
#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
#elif defined(__powerpc64__)
#define BENCHMARK_INTERNAL_CACHELINE_SIZE 128
#elif defined(__aarch64__)
#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
#elif defined(__arm__)
#if defined(__ARM_ARCH_5T__)
#define BENCHMARK_INTERNAL_CACHELINE_SIZE 32
#elif defined(__ARM_ARCH_7A__)
#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
#endif
#endif
#endif
#ifndef BENCHMARK_INTERNAL_CACHELINE_SIZE
#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
#endif
#if defined(__GNUC__)
#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED \
__attribute__((aligned(BENCHMARK_INTERNAL_CACHELINE_SIZE)))
#elif defined(_MSC_VER)
#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED \
__declspec(align(BENCHMARK_INTERNAL_CACHELINE_SIZE))
#else
#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED
#endif
#endif // BENCHMARK_MACROS_H_
+66
View File
@@ -0,0 +1,66 @@
// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BENCHMARK_MANAGERS_H_
#define BENCHMARK_MANAGERS_H_
#include <stdint.h>
#include <limits>
#include "benchmark/macros.h"
#include "benchmark/types.h"
namespace benchmark {
class MemoryManager {
public:
static constexpr int64_t TombstoneValue = std::numeric_limits<int64_t>::max();
struct Result {
Result()
: num_allocs(0),
max_bytes_used(0),
total_allocated_bytes(TombstoneValue),
net_heap_growth(TombstoneValue),
memory_iterations(0) {}
int64_t num_allocs;
int64_t max_bytes_used;
int64_t total_allocated_bytes;
int64_t net_heap_growth;
IterationCount memory_iterations;
};
virtual ~MemoryManager() {}
virtual void Start() = 0;
virtual void Stop(Result& result) = 0;
};
BENCHMARK_EXPORT
void RegisterMemoryManager(MemoryManager* memory_manager);
class ProfilerManager {
public:
virtual ~ProfilerManager() {}
virtual void AfterSetupStart() = 0;
virtual void BeforeTeardownStop() = 0;
};
BENCHMARK_EXPORT
void RegisterProfilerManager(ProfilerManager* profiler_manager);
} // namespace benchmark
#endif // BENCHMARK_MANAGERS_H_
+258
View File
@@ -0,0 +1,258 @@
// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BENCHMARK_REGISTRATION_H_
#define BENCHMARK_REGISTRATION_H_
#include "benchmark/benchmark_api.h"
#include "benchmark/macros.h"
#if defined(__clang__)
#define BENCHMARK_DISABLE_COUNTER_WARNING \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wunknown-warning-option\"") \
_Pragma("GCC diagnostic ignored \"-Wc2y-extensions\"")
#define BENCHMARK_RESTORE_COUNTER_WARNING _Pragma("GCC diagnostic pop")
#else
#define BENCHMARK_DISABLE_COUNTER_WARNING
#define BENCHMARK_RESTORE_COUNTER_WARNING
#endif
BENCHMARK_DISABLE_COUNTER_WARNING
#if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0)
#define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__
#else
#define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__
#endif
BENCHMARK_RESTORE_COUNTER_WARNING
#define BENCHMARK_PRIVATE_NAME(...) \
BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, \
__VA_ARGS__)
#define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c)
#define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c
#define BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method) \
BaseClass##_##Method##_Benchmark
#define BENCHMARK_PRIVATE_DECLARE(n) \
BENCHMARK_DISABLE_COUNTER_WARNING \
static ::benchmark::Benchmark const* const BENCHMARK_PRIVATE_NAME(n) \
BENCHMARK_RESTORE_COUNTER_WARNING BENCHMARK_UNUSED
#define BENCHMARK(...) \
BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
::benchmark::internal::make_unique< \
::benchmark::internal::FunctionBenchmark>( \
#__VA_ARGS__, \
static_cast<::benchmark::internal::Function*>(__VA_ARGS__))))
#define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a))
#define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->Args({(a1), (a2)})
#define BENCHMARK_WITH_UNIT(n, t) BENCHMARK(n)->Unit((t))
#define BENCHMARK_RANGE(n, lo, hi) BENCHMARK(n)->Range((lo), (hi))
#define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \
BENCHMARK(n)->RangePair({{(l1), (h1)}, {(l2), (h2)}})
#define BENCHMARK_CAPTURE(func, test_case_name, ...) \
BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
::benchmark::internal::make_unique< \
::benchmark::internal::FunctionBenchmark>( \
#func "/" #test_case_name, \
[](::benchmark::State& st) { func(st, __VA_ARGS__); })))
#define BENCHMARK_NAMED(func, test_case_name) \
BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
::benchmark::internal::make_unique< \
::benchmark::internal::FunctionBenchmark>( \
#func "/" #test_case_name, \
static_cast<::benchmark::internal::Function*>(func))))
#define BENCHMARK_TEMPLATE1(n, a) \
BENCHMARK_PRIVATE_DECLARE(n) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
::benchmark::internal::make_unique< \
::benchmark::internal::FunctionBenchmark>( \
#n "<" #a ">", \
static_cast<::benchmark::internal::Function*>(n<a>))))
#define BENCHMARK_TEMPLATE2(n, a, b) \
BENCHMARK_PRIVATE_DECLARE(n) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
::benchmark::internal::make_unique< \
::benchmark::internal::FunctionBenchmark>( \
#n "<" #a "," #b ">", \
static_cast<::benchmark::internal::Function*>(n<a, b>))))
#define BENCHMARK_TEMPLATE(n, ...) \
BENCHMARK_PRIVATE_DECLARE(n) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
::benchmark::internal::make_unique< \
::benchmark::internal::FunctionBenchmark>( \
#n "<" #__VA_ARGS__ ">", \
static_cast<::benchmark::internal::Function*>(n<__VA_ARGS__>))))
#define BENCHMARK_TEMPLATE1_CAPTURE(func, a, test_case_name, ...) \
BENCHMARK_CAPTURE(func<a>, test_case_name, __VA_ARGS__)
#define BENCHMARK_TEMPLATE2_CAPTURE(func, a, b, test_case_name, ...) \
BENCHMARK_PRIVATE_DECLARE(func) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
::benchmark::internal::make_unique< \
::benchmark::internal::FunctionBenchmark>( \
#func "<" #a "," #b ">" \
"/" #test_case_name, \
[](::benchmark::State& st) { func<a, b>(st, __VA_ARGS__); })))
#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
class BaseClass##_##Method##_Benchmark : public BaseClass { \
public: \
BaseClass##_##Method##_Benchmark() { \
this->SetName(#BaseClass "/" #Method); \
} \
\
protected: \
void BenchmarkCase(::benchmark::State&) override; \
};
#define BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
class BaseClass##_##Method##_Benchmark : public BaseClass<a> { \
public: \
BaseClass##_##Method##_Benchmark() { \
this->SetName(#BaseClass "<" #a ">/" #Method); \
} \
\
protected: \
void BenchmarkCase(::benchmark::State&) override; \
};
#define BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
class BaseClass##_##Method##_Benchmark : public BaseClass<a, b> { \
public: \
BaseClass##_##Method##_Benchmark() { \
this->SetName(#BaseClass "<" #a "," #b ">/" #Method); \
} \
\
protected: \
void BenchmarkCase(::benchmark::State&) override; \
};
#define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, ...) \
class BaseClass##_##Method##_Benchmark : public BaseClass<__VA_ARGS__> { \
public: \
BaseClass##_##Method##_Benchmark() { \
this->SetName(#BaseClass "<" #__VA_ARGS__ ">/" #Method); \
} \
\
protected: \
void BenchmarkCase(::benchmark::State&) override; \
};
#define BENCHMARK_DEFINE_F(BaseClass, Method) \
BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
#define BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a) \
BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
#define BENCHMARK_TEMPLATE2_DEFINE_F(BaseClass, Method, a, b) \
BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
#define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, ...) \
BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \
void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
#define BENCHMARK_REGISTER_F(BaseClass, Method) \
BENCHMARK_PRIVATE_REGISTER_F(BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method))
#define BENCHMARK_PRIVATE_REGISTER_F(TestName) \
BENCHMARK_PRIVATE_DECLARE(TestName) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
::benchmark::internal::make_unique<TestName>()))
#define BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F(BaseClass, Method) \
BaseClass##_##Method##_BenchmarkTemplate
#define BENCHMARK_TEMPLATE_METHOD_F(BaseClass, Method) \
template <class... Args> \
class BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F(BaseClass, Method) \
: public BaseClass<Args...> { \
protected: \
using Base = BaseClass<Args...>; \
void BenchmarkCase(::benchmark::State&) override; \
}; \
template <class... Args> \
void BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F( \
BaseClass, Method)<Args...>::BenchmarkCase
#define BENCHMARK_TEMPLATE_PRIVATE_INSTANTIATE_F(BaseClass, Method, \
UniqueName, ...) \
class UniqueName : public BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F( \
BaseClass, Method)<__VA_ARGS__> { \
public: \
UniqueName() { this->SetName(#BaseClass "<" #__VA_ARGS__ ">/" #Method); } \
}; \
BENCHMARK_PRIVATE_DECLARE(BaseClass##_##Method##_Benchmark) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
::benchmark::internal::make_unique<UniqueName>()))
#define BENCHMARK_TEMPLATE_INSTANTIATE_F(BaseClass, Method, ...) \
BENCHMARK_DISABLE_COUNTER_WARNING \
BENCHMARK_TEMPLATE_PRIVATE_INSTANTIATE_F( \
BaseClass, Method, BENCHMARK_PRIVATE_NAME(BaseClass##Method), \
__VA_ARGS__) \
BENCHMARK_RESTORE_COUNTER_WARNING
#define BENCHMARK_F(BaseClass, Method) \
BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
BENCHMARK_REGISTER_F(BaseClass, Method); \
void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
#define BENCHMARK_TEMPLATE1_F(BaseClass, Method, a) \
BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
BENCHMARK_REGISTER_F(BaseClass, Method); \
void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
#define BENCHMARK_TEMPLATE2_F(BaseClass, Method, a, b) \
BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
BENCHMARK_REGISTER_F(BaseClass, Method); \
void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
#define BENCHMARK_TEMPLATE_F(BaseClass, Method, ...) \
BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \
void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
#define BENCHMARK_MAIN() \
int main(int argc, char** argv) { \
benchmark::MaybeReenterWithoutASLR(argc, argv); \
char arg0_default[] = "benchmark"; \
char* args_default = reinterpret_cast<char*>(arg0_default); \
if (!argv) { \
argc = 1; \
argv = &args_default; \
} \
::benchmark::Initialize(&argc, argv); \
if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; \
::benchmark::RunSpecifiedBenchmarks(); \
::benchmark::Shutdown(); \
return 0; \
} \
int main(int, char**)
#endif // BENCHMARK_REGISTRATION_H_
+238
View File
@@ -0,0 +1,238 @@
// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BENCHMARK_REPORTER_H_
#define BENCHMARK_REPORTER_H_
#if defined(_MSC_VER)
#pragma warning(push)
// C4251: <symbol> needs to have dll-interface to be used by clients of class
#pragma warning(disable : 4251)
#endif
#include <cassert>
#include <iostream>
#include <set>
#include <string>
#include <vector>
#include "benchmark/counter.h"
#include "benchmark/macros.h"
#include "benchmark/managers.h"
#include "benchmark/statistics.h"
#include "benchmark/sysinfo.h"
#include "benchmark/types.h"
namespace benchmark {
struct BENCHMARK_EXPORT BenchmarkName {
std::string function_name;
std::string args;
std::string min_time;
std::string min_warmup_time;
std::string iterations;
std::string repetitions;
std::string time_type;
std::string threads;
std::string str() const;
};
class BENCHMARK_EXPORT BenchmarkReporter {
public:
struct Context {
CPUInfo const& cpu_info;
SystemInfo const& sys_info;
size_t name_field_width = 0;
static const char* executable_name;
Context();
};
struct BENCHMARK_EXPORT Run {
static const int64_t no_repetition_index = -1;
enum RunType { RT_Iteration, RT_Aggregate };
Run()
: run_type(RT_Iteration),
aggregate_unit(kTime),
skipped(internal::NotSkipped),
iterations(1),
threads(1),
time_unit(kNanosecond),
real_accumulated_time(0),
cpu_accumulated_time(0),
max_heapbytes_used(0),
use_real_time_for_initial_big_o(false),
complexity(oNone),
complexity_lambda(),
complexity_n(0),
statistics(),
report_big_o(false),
report_rms(false),
allocs_per_iter(0.0) {}
std::string benchmark_name() const;
BenchmarkName run_name;
int64_t family_index;
int64_t per_family_instance_index;
RunType run_type;
std::string aggregate_name;
StatisticUnit aggregate_unit;
std::string report_label;
internal::Skipped skipped;
std::string skip_message;
IterationCount iterations;
int64_t threads;
int64_t repetition_index;
int64_t repetitions;
TimeUnit time_unit;
double real_accumulated_time;
double cpu_accumulated_time;
double GetAdjustedRealTime() const;
double GetAdjustedCPUTime() const;
double max_heapbytes_used;
bool use_real_time_for_initial_big_o;
BigO complexity;
BigOFunc* complexity_lambda;
ComplexityN complexity_n;
const std::vector<internal::Statistics>* statistics;
bool report_big_o;
bool report_rms;
UserCounters counters;
MemoryManager::Result memory_result;
double allocs_per_iter;
};
struct PerFamilyRunReports {
PerFamilyRunReports() : num_runs_total(0), num_runs_done(0) {}
int num_runs_total;
int num_runs_done;
std::vector<BenchmarkReporter::Run> Runs;
};
BenchmarkReporter();
virtual bool ReportContext(const Context& context) = 0;
virtual void ReportRunsConfig(double /*min_time*/,
bool /*has_explicit_iters*/,
IterationCount /*iters*/) {}
virtual void ReportRuns(const std::vector<Run>& report) = 0;
virtual void Finalize() {}
void SetOutputStream(std::ostream* out) {
assert(out);
output_stream_ = out;
}
void SetErrorStream(std::ostream* err) {
assert(err);
error_stream_ = err;
}
std::ostream& GetOutputStream() const { return *output_stream_; }
std::ostream& GetErrorStream() const { return *error_stream_; }
virtual ~BenchmarkReporter();
static void PrintBasicContext(std::ostream* out, Context const& context);
private:
std::ostream* output_stream_;
std::ostream* error_stream_;
};
class BENCHMARK_EXPORT ConsoleReporter : public BenchmarkReporter {
public:
enum OutputOptions {
OO_None = 0,
OO_Color = 1,
OO_Tabular = 2,
OO_ColorTabular = OO_Color | OO_Tabular,
OO_Defaults = OO_ColorTabular
};
explicit ConsoleReporter(OutputOptions opts_ = OO_Defaults)
: output_options_(opts_), name_field_width_(0), printed_header_(false) {}
bool ReportContext(const Context& context) override;
void ReportRuns(const std::vector<Run>& reports) override;
protected:
virtual void PrintRunData(const Run& result);
virtual void PrintHeader(const Run& run);
OutputOptions output_options_;
size_t name_field_width_;
UserCounters prev_counters_;
bool printed_header_;
};
class BENCHMARK_EXPORT JSONReporter : public BenchmarkReporter {
public:
JSONReporter() : first_report_(true) {}
bool ReportContext(const Context& context) override;
void ReportRuns(const std::vector<Run>& reports) override;
void Finalize() override;
private:
void PrintRunData(const Run& run);
bool first_report_;
};
class BENCHMARK_EXPORT BENCHMARK_DEPRECATED_MSG(
"The CSV Reporter will be removed in a future release") CSVReporter
: public BenchmarkReporter {
public:
CSVReporter() : printed_header_(false) {}
bool ReportContext(const Context& context) override;
void ReportRuns(const std::vector<Run>& reports) override;
private:
void PrintRunData(const Run& run);
bool printed_header_;
std::set<std::string> user_counter_names_;
};
inline const char* GetTimeUnitString(TimeUnit unit) {
switch (unit) {
case kSecond:
return "s";
case kMillisecond:
return "ms";
case kMicrosecond:
return "us";
case kNanosecond:
return "ns";
}
BENCHMARK_UNREACHABLE();
}
inline double GetTimeUnitMultiplier(TimeUnit unit) {
switch (unit) {
case kSecond:
return 1;
case kMillisecond:
return 1e3;
case kMicrosecond:
return 1e6;
case kNanosecond:
return 1e9;
}
BENCHMARK_UNREACHABLE();
}
} // namespace benchmark
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#endif // BENCHMARK_REPORTER_H_
+282
View File
@@ -0,0 +1,282 @@
// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BENCHMARK_STATE_H_
#define BENCHMARK_STATE_H_
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4251 4324)
#endif
#include <cassert>
#include <string>
#include <vector>
#include "benchmark/counter.h"
#include "benchmark/macros.h"
#include "benchmark/statistics.h"
#include "benchmark/types.h"
namespace benchmark {
namespace internal {
class BenchmarkInstance;
class ThreadTimer;
class ThreadManager;
class PerfCountersMeasurement;
} // namespace internal
class ProfilerManager;
class BENCHMARK_EXPORT BENCHMARK_INTERNAL_CACHELINE_ALIGNED State {
public:
struct StateIterator;
friend struct StateIterator;
inline BENCHMARK_ALWAYS_INLINE StateIterator begin();
inline BENCHMARK_ALWAYS_INLINE StateIterator end();
inline bool KeepRunning();
inline bool KeepRunningBatch(IterationCount n);
void PauseTiming();
void ResumeTiming();
void SkipWithMessage(const std::string& msg);
void SkipWithError(const std::string& msg);
bool skipped() const { return internal::NotSkipped != skipped_; }
bool error_occurred() const { return internal::SkippedWithError == skipped_; }
void SetIterationTime(double seconds);
BENCHMARK_ALWAYS_INLINE
void SetBytesProcessed(int64_t bytes) {
counters["bytes_per_second"] =
Counter(static_cast<double>(bytes), Counter::kIsRate, Counter::kIs1024);
}
BENCHMARK_ALWAYS_INLINE
int64_t bytes_processed() const {
if (counters.find("bytes_per_second") != counters.end())
return static_cast<int64_t>(counters.at("bytes_per_second"));
return 0;
}
BENCHMARK_ALWAYS_INLINE
void SetComplexityN(ComplexityN complexity_n) {
complexity_n_ = complexity_n;
}
BENCHMARK_ALWAYS_INLINE
ComplexityN complexity_length_n() const { return complexity_n_; }
BENCHMARK_ALWAYS_INLINE
void SetItemsProcessed(int64_t items) {
counters["items_per_second"] =
Counter(static_cast<double>(items), benchmark::Counter::kIsRate);
}
BENCHMARK_ALWAYS_INLINE
int64_t items_processed() const {
if (counters.find("items_per_second") != counters.end())
return static_cast<int64_t>(counters.at("items_per_second"));
return 0;
}
void SetLabel(const std::string& label);
BENCHMARK_ALWAYS_INLINE
int64_t range(std::size_t pos = 0) const {
assert(range_.size() > pos);
return range_[pos];
}
BENCHMARK_DEPRECATED_MSG("use 'range(0)' instead")
int64_t range_x() const { return range(0); }
BENCHMARK_DEPRECATED_MSG("use 'range(1)' instead")
int64_t range_y() const { return range(1); }
BENCHMARK_ALWAYS_INLINE
int threads() const { return threads_; }
BENCHMARK_ALWAYS_INLINE
int thread_index() const { return thread_index_; }
BENCHMARK_ALWAYS_INLINE
IterationCount iterations() const {
if (BENCHMARK_BUILTIN_EXPECT(!started_, false)) {
return 0;
}
return max_iterations - total_iterations_ + batch_leftover_;
}
BENCHMARK_ALWAYS_INLINE
std::string name() const { return name_; }
size_t range_size() const { return range_.size(); }
private:
IterationCount total_iterations_;
IterationCount batch_leftover_;
public:
const IterationCount max_iterations;
private:
bool started_;
bool finished_;
internal::Skipped skipped_;
std::vector<int64_t> range_;
ComplexityN complexity_n_;
public:
UserCounters counters;
private:
State(std::string name, IterationCount max_iters,
const std::vector<int64_t>& ranges, int thread_i, int n_threads,
internal::ThreadTimer* timer, internal::ThreadManager* manager,
internal::PerfCountersMeasurement* perf_counters_measurement,
ProfilerManager* profiler_manager);
void StartKeepRunning();
inline bool KeepRunningInternal(IterationCount n, bool is_batch);
void FinishKeepRunning();
const std::string name_;
const int thread_index_;
const int threads_;
internal::ThreadTimer* const timer_;
internal::ThreadManager* const manager_;
internal::PerfCountersMeasurement* const perf_counters_measurement_;
ProfilerManager* const profiler_manager_;
friend class internal::BenchmarkInstance;
};
inline BENCHMARK_ALWAYS_INLINE bool State::KeepRunning() {
return KeepRunningInternal(1, /*is_batch=*/false);
}
inline BENCHMARK_ALWAYS_INLINE bool State::KeepRunningBatch(IterationCount n) {
return KeepRunningInternal(n, /*is_batch=*/true);
}
inline BENCHMARK_ALWAYS_INLINE bool State::KeepRunningInternal(IterationCount n,
bool is_batch) {
assert(n > 0);
assert(is_batch || n == 1);
if (BENCHMARK_BUILTIN_EXPECT(total_iterations_ >= n, true)) {
total_iterations_ -= n;
return true;
}
if (!started_) {
StartKeepRunning();
if (!skipped() && total_iterations_ >= n) {
total_iterations_ -= n;
return true;
}
}
if (is_batch && total_iterations_ != 0) {
batch_leftover_ = n - total_iterations_;
total_iterations_ = 0;
return true;
}
FinishKeepRunning();
return false;
}
struct State::StateIterator {
struct BENCHMARK_UNUSED Value {};
typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef Value reference;
typedef Value pointer;
typedef std::ptrdiff_t difference_type;
private:
friend class State;
BENCHMARK_ALWAYS_INLINE
StateIterator() : cached_(0), parent_() {}
BENCHMARK_ALWAYS_INLINE
explicit StateIterator(State* st)
: cached_(st->skipped() ? 0 : st->max_iterations), parent_(st) {}
public:
BENCHMARK_ALWAYS_INLINE
Value operator*() const { return Value(); }
BENCHMARK_ALWAYS_INLINE
StateIterator& operator++() {
assert(cached_ > 0);
--cached_;
return *this;
}
BENCHMARK_ALWAYS_INLINE
bool operator!=(StateIterator const&) const {
if (BENCHMARK_BUILTIN_EXPECT(cached_ != 0, true)) return true;
parent_->FinishKeepRunning();
return false;
}
private:
IterationCount cached_;
State* const parent_;
};
inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::begin() {
return StateIterator(this);
}
inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::end() {
StartKeepRunning();
return StateIterator();
}
class ScopedPauseTiming {
public:
explicit ScopedPauseTiming(State& state) : state_(state) {
state_.PauseTiming();
}
~ScopedPauseTiming() { state_.ResumeTiming(); }
ScopedPauseTiming(const ScopedPauseTiming&) = delete;
void operator=(const ScopedPauseTiming&) = delete;
ScopedPauseTiming(ScopedPauseTiming&&) = delete;
void operator=(ScopedPauseTiming&&) = delete;
private:
State& state_;
};
} // namespace benchmark
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#endif // BENCHMARK_STATE_H_
+65
View File
@@ -0,0 +1,65 @@
// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BENCHMARK_STATISTICS_H_
#define BENCHMARK_STATISTICS_H_
#include <string>
#include <vector>
#include "benchmark/types.h"
namespace benchmark {
enum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLambda };
typedef int64_t ComplexityN;
enum StatisticUnit { kTime, kPercentage };
typedef double(BigOFunc)(ComplexityN);
typedef double(StatisticsFunc)(const std::vector<double>&);
namespace internal {
struct Statistics {
std::string name_;
StatisticsFunc* compute_;
StatisticUnit unit_;
Statistics(const std::string& name, StatisticsFunc* compute,
StatisticUnit unit = kTime)
: name_(name), compute_(compute), unit_(unit) {}
};
enum AggregationReportMode : unsigned {
ARM_Unspecified = 0,
ARM_Default = 1U << 0U,
ARM_FileReportAggregatesOnly = 1U << 1U,
ARM_DisplayReportAggregatesOnly = 1U << 2U,
ARM_ReportAggregatesOnly =
ARM_FileReportAggregatesOnly | ARM_DisplayReportAggregatesOnly
};
enum Skipped : unsigned {
NotSkipped = 0,
SkippedWithMessage,
SkippedWithError
};
} // namespace internal
} // namespace benchmark
#endif // BENCHMARK_STATISTICS_H_
+71
View File
@@ -0,0 +1,71 @@
// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BENCHMARK_SYSINFO_H_
#define BENCHMARK_SYSINFO_H_
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4251)
#endif
#include <string>
#include <vector>
#include "benchmark/macros.h"
namespace benchmark {
struct BENCHMARK_EXPORT CPUInfo {
struct CacheInfo {
std::string type;
int level;
int size;
int num_sharing;
};
enum Scaling { UNKNOWN, ENABLED, DISABLED };
int num_cpus;
Scaling scaling;
double cycles_per_second;
std::vector<CacheInfo> caches;
std::vector<double> load_avg;
static const CPUInfo& Get();
private:
CPUInfo();
BENCHMARK_DISALLOW_COPY_AND_ASSIGN(CPUInfo);
};
struct BENCHMARK_EXPORT SystemInfo {
enum class ASLR { UNKNOWN, ENABLED, DISABLED };
std::string name;
ASLR ASLRStatus;
static const SystemInfo& Get();
private:
SystemInfo();
BENCHMARK_DISALLOW_COPY_AND_ASSIGN(SystemInfo);
};
} // namespace benchmark
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#endif // BENCHMARK_SYSINFO_H_
+50
View File
@@ -0,0 +1,50 @@
// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BENCHMARK_TYPES_H_
#define BENCHMARK_TYPES_H_
#include <stdint.h>
#include <functional>
#include <memory>
#include <string>
#include "benchmark/export.h"
namespace benchmark {
namespace internal {
#if (__cplusplus < 201402L || (defined(_MSC_VER) && _MSVC_LANG < 201402L))
template <typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
#else
using ::std::make_unique;
#endif
} // namespace internal
class BenchmarkReporter;
class State;
using IterationCount = int64_t;
using callback_function = std::function<void(const benchmark::State&)>;
enum TimeUnit { kNanosecond, kMicrosecond, kMillisecond, kSecond };
} // namespace benchmark
#endif // BENCHMARK_TYPES_H_
+152
View File
@@ -0,0 +1,152 @@
// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BENCHMARK_UTILS_H_
#define BENCHMARK_UTILS_H_
#include <atomic>
#include <type_traits>
#include <utility>
#include "benchmark/export.h"
#include "benchmark/macros.h"
namespace benchmark {
namespace internal {
BENCHMARK_EXPORT void UseCharPointer(char const volatile*);
}
#if (!defined(__GNUC__) && !defined(__clang__)) || defined(__pnacl__) || \
defined(__EMSCRIPTEN__)
#define BENCHMARK_HAS_NO_INLINE_ASSEMBLY
#endif
inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {
std::atomic_signal_fence(std::memory_order_acq_rel);
}
#define BENCHMARK_DONOTOPTIMIZE_CONST_REF_DEPRECATED_MSG \
"DoNotOptimize(T const&) can permit undesired compiler optimizations. " \
"Pass a non-const lvalue instead; if the argument is an expression result, " \
"store it in a local variable first."
#ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY
#if !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER)
template <class Tp>
BENCHMARK_DEPRECATED_MSG(BENCHMARK_DONOTOPTIMIZE_CONST_REF_DEPRECATED_MSG)
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
asm volatile("" : : "r,m"(value) : "memory");
}
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {
#if defined(__clang__)
asm volatile("" : "+r,m"(value) : : "memory");
#else
asm volatile("" : "+m,r"(value) : : "memory");
#endif
}
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {
#if defined(__clang__)
asm volatile("" : "+r,m"(value) : : "memory");
#else
asm volatile("" : "+m,r"(value) : : "memory");
#endif
}
#elif (__GNUC__ >= 5)
template <class Tp>
BENCHMARK_DEPRECATED_MSG(BENCHMARK_DONOTOPTIMIZE_CONST_REF_DEPRECATED_MSG)
inline BENCHMARK_ALWAYS_INLINE
typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
(sizeof(Tp) <= sizeof(Tp*))>::type
DoNotOptimize(Tp const& value) {
asm volatile("" : : "r,m"(value) : "memory");
}
template <class Tp>
BENCHMARK_DEPRECATED_MSG(BENCHMARK_DONOTOPTIMIZE_CONST_REF_DEPRECATED_MSG)
inline BENCHMARK_ALWAYS_INLINE
typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
(sizeof(Tp) > sizeof(Tp*))>::type
DoNotOptimize(Tp const& value) {
asm volatile("" : : "m"(value) : "memory");
}
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE
typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
(sizeof(Tp) <= sizeof(Tp*))>::type
DoNotOptimize(Tp& value) {
asm volatile("" : "+m,r"(value) : : "memory");
}
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE
typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
(sizeof(Tp) > sizeof(Tp*))>::type
DoNotOptimize(Tp& value) {
asm volatile("" : "+m"(value) : : "memory");
}
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE
typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
(sizeof(Tp) <= sizeof(Tp*))>::type
DoNotOptimize(Tp&& value) {
asm volatile("" : "+m,r"(value) : : "memory");
}
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE
typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
(sizeof(Tp) > sizeof(Tp*))>::type
DoNotOptimize(Tp&& value) {
asm volatile("" : "+m"(value) : : "memory");
}
#endif
#elif defined(_MSC_VER)
template <class Tp>
BENCHMARK_DEPRECATED_MSG(BENCHMARK_DONOTOPTIMIZE_CONST_REF_DEPRECATED_MSG)
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
ClobberMemory();
}
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
ClobberMemory();
}
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
ClobberMemory();
}
#else
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
}
#endif
#undef BENCHMARK_DONOTOPTIMIZE_CONST_REF_DEPRECATED_MSG
} // end namespace benchmark
#endif // BENCHMARK_UTILS_H_