[upstream_utils] Upgrade to Google Benchmark 1.9.5 (#8760)

This commit is contained in:
Tyler Veness
2026-04-11 16:52:24 -07:00
committed by GitHub
parent 042567d0ba
commit 7e9138f8c1
24 changed files with 215 additions and 98 deletions

View File

@@ -42,6 +42,12 @@ jobs:
./argparse_lib.py clone
./argparse_lib.py copy-src
./argparse_lib.py format-patch
- name: Run benchmark.py
run: |
cd upstream_utils
./benchmark.py clone
./benchmark.py copy-src
./benchmark.py format-patch
- name: Run double-conversion.py
run: |
cd upstream_utils

View File

@@ -103,7 +103,7 @@ BENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {128, 512}});
// arbitrary set of arguments to run the microbenchmark on.
// The following example enumerates a dense range on
// one parameter, and a sparse range on the second.
static void CustomArguments(benchmark::internal::Benchmark* b) {
static void CustomArguments(benchmark::Benchmark* b) {
for (int i = 0; i <= 10; ++i)
for (int j = 32; j <= 1024*1024; j *= 8)
b->Args({i, j});
@@ -171,7 +171,6 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond);
#include <cassert>
#include <cstddef>
#include <functional>
#include <initializer_list>
#include <iosfwd>
#include <limits>
#include <map>
@@ -239,6 +238,16 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond);
_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)
@@ -476,10 +485,11 @@ void RegisterProfilerManager(ProfilerManager* profiler_manager);
// Add a key-value pair to output as part of the context stanza in the report.
BENCHMARK_EXPORT
void AddCustomContext(const std::string& key, const std::string& value);
void AddCustomContext(std::string key, std::string value);
class Benchmark;
namespace internal {
class Benchmark;
class BenchmarkImp;
class BenchmarkFamilies;
@@ -611,6 +621,17 @@ inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
_ReadWriteBarrier();
}
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
_ReadWriteBarrier();
}
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
_ReadWriteBarrier();
}
#else
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {
@@ -956,6 +977,8 @@ class BENCHMARK_EXPORT BENCHMARK_INTERNAL_CACHELINE_ALIGNED State {
BENCHMARK_ALWAYS_INLINE
std::string name() const { return name_; }
size_t range_size() const { return range_.size(); }
private:
// items we expect on the first cache line (ie 64 bytes of the struct)
// When total_iterations_ is 0, KeepRunning() and friends will return false.
@@ -1102,20 +1125,15 @@ struct ThreadRunnerBase {
virtual void RunThreads(const std::function<void(int)>& fn) = 0;
};
namespace internal {
// Define alias of ThreadRunner factory function type
using threadrunner_factory =
std::function<std::unique_ptr<ThreadRunnerBase>(int)>;
typedef void(Function)(State&);
// ------------------------------------------------------
// Benchmark registration object. The BENCHMARK() macro expands
// into an internal::Benchmark* object. Various methods can
// be called on this object to change the properties of the benchmark.
// Each method returns "this" so that multiple method calls can
// chained into one expression.
// Benchmark registration object. The BENCHMARK() macro expands into a
// Benchmark* object. Various methods can be called on this object to
// change the properties of the benchmark. Each method returns "this" so
// that multiple method calls can chained into one expression.
class BENCHMARK_EXPORT Benchmark {
public:
virtual ~Benchmark();
@@ -1206,7 +1224,7 @@ class BENCHMARK_EXPORT Benchmark {
// Pass this benchmark object to *func, which can customize
// the benchmark by calling various methods like Arg, Args,
// Threads, etc.
Benchmark* Apply(void (*custom_arguments)(Benchmark* benchmark));
Benchmark* Apply(const std::function<void(Benchmark* benchmark)>&);
// Set the range multiplier for non-dense range. If not called, the range
// multiplier kRangeMultiplier will be used.
@@ -1329,11 +1347,11 @@ class BENCHMARK_EXPORT Benchmark {
const char* GetArgName(int arg) const;
private:
friend class BenchmarkFamilies;
friend class BenchmarkInstance;
friend class internal::BenchmarkFamilies;
friend class internal::BenchmarkInstance;
std::string name_;
AggregationReportMode aggregation_report_mode_;
internal::AggregationReportMode aggregation_report_mode_;
std::vector<std::string> arg_names_; // Args for all benchmark runs
std::vector<std::vector<int64_t>> args_; // Args for all benchmark runs
@@ -1350,7 +1368,7 @@ class BENCHMARK_EXPORT Benchmark {
bool use_manual_time_;
BigO complexity_;
BigOFunc* complexity_lambda_;
std::vector<Statistics> statistics_;
std::vector<internal::Statistics> statistics_;
std::vector<int> thread_counts_;
callback_function setup_;
@@ -1361,17 +1379,28 @@ class BENCHMARK_EXPORT Benchmark {
BENCHMARK_DISALLOW_COPY_AND_ASSIGN(Benchmark);
};
namespace internal {
// clang-format off
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;
// clang-format on
typedef void(Function)(State&);
} // namespace internal
// Create and register a benchmark with the specified 'name' that invokes
// the specified functor 'fn'.
//
// RETURNS: A pointer to the registered benchmark.
internal::Benchmark* RegisterBenchmark(const std::string& name,
internal::Function* fn);
Benchmark* RegisterBenchmark(const std::string& name, internal::Function* fn);
template <class Lambda>
internal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn);
Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn);
// Remove all registered benchmarks. All pointers to previously registered
// benchmarks are invalidated.
@@ -1380,7 +1409,7 @@ BENCHMARK_EXPORT void ClearRegisteredBenchmarks();
namespace internal {
// The class used to hold all Benchmarks created from static function.
// (ie those created using the BENCHMARK(...) macros.
class BENCHMARK_EXPORT FunctionBenchmark : public Benchmark {
class BENCHMARK_EXPORT FunctionBenchmark : public benchmark::Benchmark {
public:
FunctionBenchmark(const std::string& name, Function* func)
: Benchmark(name), func_(func) {}
@@ -1392,7 +1421,7 @@ class BENCHMARK_EXPORT FunctionBenchmark : public Benchmark {
};
template <class Lambda>
class LambdaBenchmark : public Benchmark {
class LambdaBenchmark : public benchmark::Benchmark {
public:
void Run(State& st) override { lambda_(st); }
@@ -1406,7 +1435,7 @@ class LambdaBenchmark : public Benchmark {
};
} // namespace internal
inline internal::Benchmark* RegisterBenchmark(const std::string& name,
inline Benchmark* RegisterBenchmark(const std::string& name,
internal::Function* fn) {
return internal::RegisterBenchmarkInternal(
::benchmark::internal::make_unique<internal::FunctionBenchmark>(name,
@@ -1414,7 +1443,7 @@ inline internal::Benchmark* RegisterBenchmark(const std::string& name,
}
template <class Lambda>
internal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn) {
Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn) {
using BenchType =
internal::LambdaBenchmark<typename std::decay<Lambda>::type>;
return internal::RegisterBenchmarkInternal(
@@ -1423,16 +1452,16 @@ internal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn) {
}
template <class Lambda, class... Args>
internal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn,
Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn,
Args&&... args) {
return benchmark::RegisterBenchmark(
name, [=](benchmark::State& st) { fn(st, args...); });
}
// The base class for all fixture tests.
class Fixture : public internal::Benchmark {
class Fixture : public Benchmark {
public:
Fixture() : internal::Benchmark("") {}
Fixture() : Benchmark("") {}
void Run(State& st) override {
this->SetUp(st);
@@ -1455,14 +1484,29 @@ class Fixture : public internal::Benchmark {
// ------------------------------------------------------
// Macro to register benchmarks
// clang-format off
#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
// clang-format on
// Check that __COUNTER__ is defined and that __COUNTER__ increases by 1
// every time it is expanded. X + 1 == X + 0 is used in case X is defined to be
// empty. If X is empty the expression becomes (+1 == +0).
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
// Helpers for generating unique variable names
#define BENCHMARK_PRIVATE_NAME(...) \
@@ -1476,16 +1520,18 @@ class Fixture : public internal::Benchmark {
BaseClass##_##Method##_Benchmark
#define BENCHMARK_PRIVATE_DECLARE(n) \
BENCHMARK_DISABLE_COUNTER_WARNING \
/* NOLINTNEXTLINE(misc-use-anonymous-namespace) */ \
static ::benchmark::internal::Benchmark const* const BENCHMARK_PRIVATE_NAME( \
n) BENCHMARK_UNUSED
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__, \
__VA_ARGS__)))
::benchmark::internal::FunctionBenchmark>( \
#__VA_ARGS__, \
static_cast<::benchmark::internal::Function*>(__VA_ARGS__))))
// Old-style macros
#define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a))
@@ -1526,21 +1572,25 @@ class Fixture : public internal::Benchmark {
BENCHMARK_PRIVATE_DECLARE(n) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
::benchmark::internal::make_unique< \
::benchmark::internal::FunctionBenchmark>(#n "<" #a ">", n<a>)))
::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 ">", \
n<a, b>)))
::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__ ">", n<__VA_ARGS__>)))
#n "<" #__VA_ARGS__ ">", \
static_cast<::benchmark::internal::Function*>(n<__VA_ARGS__>))))
// This will register a benchmark for a templatized function,
// with the additional arguments specified by `...`.
@@ -1661,9 +1711,11 @@ class Fixture : public internal::Benchmark {
::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__)
__VA_ARGS__) \
BENCHMARK_RESTORE_COUNTER_WARNING
// This macro will define and register a benchmark within a fixture class.
#define BENCHMARK_F(BaseClass, Method) \
@@ -1798,6 +1850,7 @@ class BENCHMARK_EXPORT BenchmarkReporter {
complexity(oNone),
complexity_lambda(),
complexity_n(0),
statistics(),
report_big_o(false),
report_rms(false),
allocs_per_iter(0.0) {}

View File

@@ -708,11 +708,12 @@ void RegisterProfilerManager(ProfilerManager* manager) {
internal::profiler_manager = manager;
}
void AddCustomContext(const std::string& key, const std::string& value) {
void AddCustomContext(std::string key, std::string value) {
if (internal::global_context == nullptr) {
internal::global_context = new std::map<std::string, std::string>();
}
if (!internal::global_context->emplace(key, value).second) {
if (!internal::global_context->emplace(std::move(key), std::move(value))
.second) {
std::cerr << "Failed to add custom context \"" << key << "\" as it already "
<< "exists with value \"" << value << "\"\n";
}
@@ -722,6 +723,7 @@ namespace internal {
void (*HelperPrintf)();
namespace {
void PrintUsageAndExit() {
HelperPrintf();
std::flush(std::cout);
@@ -810,6 +812,8 @@ void ParseCommandLineFlags(int* argc, char** argv) {
}
}
} // end namespace
int InitializeStreams() {
static std::ios_base::Init init;
return 0;

View File

@@ -7,7 +7,8 @@
namespace benchmark {
namespace internal {
BenchmarkInstance::BenchmarkInstance(Benchmark* benchmark, int family_idx,
BenchmarkInstance::BenchmarkInstance(benchmark::Benchmark* benchmark,
int family_idx,
int per_family_instance_idx,
const std::vector<int64_t>& args,
int thread_count)

View File

@@ -17,7 +17,7 @@ namespace internal {
// Information kept per benchmark we may want to run
class BenchmarkInstance {
public:
BenchmarkInstance(Benchmark* benchmark, int family_idx,
BenchmarkInstance(benchmark::Benchmark* benchmark, int family_idx,
int per_family_instance_idx,
const std::vector<int64_t>& args, int thread_count);
@@ -52,7 +52,7 @@ class BenchmarkInstance {
private:
BenchmarkName name_;
Benchmark& benchmark_;
benchmark::Benchmark& benchmark_;
const int family_index_;
const int per_family_instance_index_;
AggregationReportMode aggregation_report_mode_;

View File

@@ -75,7 +75,7 @@ class BenchmarkFamilies {
static BenchmarkFamilies* GetInstance();
// Registers a benchmark family and returns the index assigned to it.
size_t AddBenchmark(std::unique_ptr<Benchmark> family);
size_t AddBenchmark(std::unique_ptr<benchmark::Benchmark> family);
// Clear all registered benchmark families.
void ClearBenchmarks();
@@ -89,7 +89,7 @@ class BenchmarkFamilies {
private:
BenchmarkFamilies() {}
std::vector<std::unique_ptr<Benchmark>> families_;
std::vector<std::unique_ptr<benchmark::Benchmark>> families_;
Mutex mutex_;
};
@@ -98,7 +98,8 @@ BenchmarkFamilies* BenchmarkFamilies::GetInstance() {
return &instance;
}
size_t BenchmarkFamilies::AddBenchmark(std::unique_ptr<Benchmark> family) {
size_t BenchmarkFamilies::AddBenchmark(
std::unique_ptr<benchmark::Benchmark> family) {
MutexLock l(mutex_);
size_t index = families_.size();
families_.push_back(std::move(family));
@@ -135,7 +136,7 @@ bool BenchmarkFamilies::FindBenchmarks(
int next_family_index = 0;
MutexLock l(mutex_);
for (std::unique_ptr<Benchmark>& family : families_) {
for (std::unique_ptr<benchmark::Benchmark>& family : families_) {
int family_index = next_family_index;
int per_family_instance_index = 0;
@@ -179,7 +180,7 @@ bool BenchmarkFamilies::FindBenchmarks(
++per_family_instance_index;
// Only bump the next family index once we've estabilished that
// Only bump the next family index once we've established that
// at least one instance of this family will be run.
if (next_family_index == family_index) {
++next_family_index;
@@ -191,8 +192,9 @@ bool BenchmarkFamilies::FindBenchmarks(
return true;
}
Benchmark* RegisterBenchmarkInternal(std::unique_ptr<Benchmark> bench) {
Benchmark* bench_ptr = bench.get();
benchmark::Benchmark* RegisterBenchmarkInternal(
std::unique_ptr<benchmark::Benchmark> bench) {
benchmark::Benchmark* bench_ptr = bench.get();
BenchmarkFamilies* families = BenchmarkFamilies::GetInstance();
families->AddBenchmark(std::move(bench));
return bench_ptr;
@@ -206,13 +208,15 @@ bool FindBenchmarksInternal(const std::string& re,
return BenchmarkFamilies::GetInstance()->FindBenchmarks(re, benchmarks, Err);
}
} // end namespace internal
//=============================================================================//
// Benchmark
//=============================================================================//
Benchmark::Benchmark(const std::string& name)
: name_(name),
aggregation_report_mode_(ARM_Unspecified),
aggregation_report_mode_(internal::ARM_Unspecified),
time_unit_(GetDefaultTimeUnit()),
use_default_time_unit_(true),
range_multiplier_(kRangeMultiplier),
@@ -253,7 +257,7 @@ Benchmark* Benchmark::Unit(TimeUnit unit) {
Benchmark* Benchmark::Range(int64_t start, int64_t limit) {
BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);
std::vector<int64_t> arglist;
AddRange(&arglist, start, limit, range_multiplier_);
internal::AddRange(&arglist, start, limit, range_multiplier_);
for (int64_t i : arglist) {
args_.push_back({i});
@@ -266,7 +270,7 @@ Benchmark* Benchmark::Ranges(
BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(ranges.size()));
std::vector<std::vector<int64_t>> arglists(ranges.size());
for (std::size_t i = 0; i < ranges.size(); i++) {
AddRange(&arglists[i], ranges[i].first, ranges[i].second,
internal::AddRange(&arglists[i], ranges[i].first, ranges[i].second,
range_multiplier_);
}
@@ -330,7 +334,8 @@ Benchmark* Benchmark::Args(const std::vector<int64_t>& args) {
return this;
}
Benchmark* Benchmark::Apply(void (*custom_arguments)(Benchmark* benchmark)) {
Benchmark* Benchmark::Apply(
const std::function<void(Benchmark* benchmark)>& custom_arguments) {
custom_arguments(this);
return this;
}
@@ -381,8 +386,8 @@ Benchmark* Benchmark::MinWarmUpTime(double t) {
Benchmark* Benchmark::Iterations(IterationCount n) {
BM_CHECK(n > 0);
BM_CHECK(IsZero(min_time_));
BM_CHECK(IsZero(min_warmup_time_));
BM_CHECK(internal::IsZero(min_time_));
BM_CHECK(internal::IsZero(min_warmup_time_));
iterations_ = n;
return this;
}
@@ -394,21 +399,23 @@ Benchmark* Benchmark::Repetitions(int n) {
}
Benchmark* Benchmark::ReportAggregatesOnly(bool value) {
aggregation_report_mode_ = value ? ARM_ReportAggregatesOnly : ARM_Default;
aggregation_report_mode_ =
value ? internal::ARM_ReportAggregatesOnly : internal::ARM_Default;
return this;
}
Benchmark* Benchmark::DisplayAggregatesOnly(bool value) {
// If we were called, the report mode is no longer 'unspecified', in any case.
using internal::AggregationReportMode;
aggregation_report_mode_ = static_cast<AggregationReportMode>(
aggregation_report_mode_ | ARM_Default);
aggregation_report_mode_ | internal::ARM_Default);
if (value) {
aggregation_report_mode_ = static_cast<AggregationReportMode>(
aggregation_report_mode_ | ARM_DisplayReportAggregatesOnly);
aggregation_report_mode_ | internal::ARM_DisplayReportAggregatesOnly);
} else {
aggregation_report_mode_ = static_cast<AggregationReportMode>(
aggregation_report_mode_ & ~ARM_DisplayReportAggregatesOnly);
aggregation_report_mode_ & ~internal::ARM_DisplayReportAggregatesOnly);
}
return this;
@@ -462,7 +469,7 @@ Benchmark* Benchmark::ThreadRange(int min_threads, int max_threads) {
BM_CHECK_GT(min_threads, 0);
BM_CHECK_GE(max_threads, min_threads);
AddRange(&thread_counts_, min_threads, max_threads, 2);
internal::AddRange(&thread_counts_, min_threads, max_threads, 2);
return this;
}
@@ -514,6 +521,8 @@ TimeUnit Benchmark::GetTimeUnit() const {
return use_default_time_unit_ ? GetDefaultTimeUnit() : time_unit_;
}
namespace internal {
//=============================================================================//
// FunctionBenchmark
//=============================================================================//

View File

@@ -3,6 +3,7 @@
#include <algorithm>
#include <limits>
#include <type_traits>
#include <vector>
#include "check.h"

View File

@@ -123,7 +123,12 @@ BenchmarkReporter::Run CreateRunReport(
: 0;
}
internal::Finish(&report.counters, results.iterations, seconds,
// The CPU time is the total time taken by all thread. If we used that as
// the denominator, we'd be calculating the rate per thread here. This is
// why we have to divide the total cpu_time by the number of threads for
// global counters to get a global rate.
const double thread_seconds = seconds / b.threads();
internal::Finish(&report.counters, results.iterations, thread_seconds,
b.threads());
}
return report;
@@ -191,7 +196,7 @@ class ThreadRunnerDefault : public ThreadRunnerBase {
explicit ThreadRunnerDefault(int num_threads)
: pool(static_cast<size_t>(num_threads - 1)) {}
void RunThreads(const std::function<void(int)>& fn) final {
void RunThreads(const std::function<void(int)>& fn) override final {
// Run all but one thread in separate threads
for (std::size_t ti = 0; ti < pool.size(); ++ti) {
pool[ti] = std::thread(fn, static_cast<int>(ti + 1));
@@ -212,7 +217,8 @@ class ThreadRunnerDefault : public ThreadRunnerBase {
};
std::unique_ptr<ThreadRunnerBase> GetThreadRunner(
const threadrunner_factory& userThreadRunnerFactory, int num_threads) {
const benchmark::threadrunner_factory& userThreadRunnerFactory,
int num_threads) {
return userThreadRunnerFactory
? userThreadRunnerFactory(num_threads)
: std::make_unique<ThreadRunnerDefault>(num_threads);
@@ -400,7 +406,7 @@ bool BenchmarkRunner::ShouldReportIterationResults(
}
double BenchmarkRunner::GetMinTimeToApply() const {
// In order to re-use functionality to run and measure benchmarks for running
// In order to reuse functionality to run and measure benchmarks for running
// a warmup phase of the benchmark, we need a way of telling whether to apply
// min_time or min_warmup_time. This function will figure out if we are in the
// warmup phase and therefore need to apply min_warmup_time or if we already

View File

@@ -5,6 +5,8 @@
#include <iostream>
#include <string>
#include "internal_macros.h"
namespace benchmark {
enum LogColor {
COLOR_DEFAULT,
@@ -17,11 +19,14 @@ enum LogColor {
COLOR_WHITE
};
PRINTF_FORMAT_STRING_FUNC(1, 0)
std::string FormatString(const char* msg, va_list args);
std::string FormatString(const char* msg, ...);
PRINTF_FORMAT_STRING_FUNC(1, 2) std::string FormatString(const char* msg, ...);
PRINTF_FORMAT_STRING_FUNC(3, 0)
void ColorPrintf(std::ostream& out, LogColor color, const char* fmt,
va_list args);
PRINTF_FORMAT_STRING_FUNC(3, 4)
void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, ...);
// Returns true if stdout appears to be a terminal that supports colored

View File

@@ -179,6 +179,8 @@ std::map<std::string, std::string> KvPairsFromEnv(
return value;
}
namespace {
// Parses a string as a command line flag. The string should have
// the format "--flag=value". When def_optional is true, the "=value"
// part can be omitted.
@@ -217,6 +219,8 @@ const char* ParseFlagValue(const char* str, const char* flag,
return flag_end + 1;
}
} // end namespace
BENCHMARK_EXPORT
bool ParseBoolFlag(const char* str, const char* flag, bool* value) {
// Gets the value of the flag as a string.

View File

@@ -17,7 +17,6 @@
#include "complexity.h"
#include <algorithm>
#include <cmath>
#include "benchmark/benchmark.h"
@@ -25,6 +24,8 @@
namespace benchmark {
namespace {
// Internal function to calculate the different scalability forms
BigOFunc* FittingCurve(BigO complexity) {
switch (complexity) {
@@ -48,6 +49,8 @@ BigOFunc* FittingCurve(BigO complexity) {
}
}
} // end namespace
// Function to return an string for the calculated complexity
std::string GetBigOString(BigO complexity) {
switch (complexity) {
@@ -68,6 +71,8 @@ std::string GetBigOString(BigO complexity) {
}
}
namespace {
// Find the coefficient for the high-order term in the running time, by
// minimizing the sum of squares of relative error, for the fitting curve
// given by the lambda expression.
@@ -152,6 +157,8 @@ LeastSq MinimalLeastSq(const std::vector<ComplexityN>& n,
return best_fit;
}
} // end namespace
std::vector<BenchmarkReporter::Run> ComputeBigO(
const std::vector<BenchmarkReporter::Run>& reports) {
typedef BenchmarkReporter::Run Run;

View File

@@ -97,6 +97,7 @@ void ConsoleReporter::ReportRuns(const std::vector<Run>& reports) {
}
}
PRINTF_FORMAT_STRING_FUNC(3, 4)
static void IgnoreColorPrint(std::ostream& out, LogColor /*unused*/,
const char* fmt, ...) {
va_list args;

View File

@@ -17,6 +17,8 @@
namespace benchmark {
namespace internal {
namespace {
double Finish(Counter const& c, IterationCount iterations, double cpu_time,
double num_threads) {
double v = c.value;
@@ -39,6 +41,8 @@ double Finish(Counter const& c, IterationCount iterations, double cpu_time,
return v;
}
} // namespace
void Finish(UserCounters* l, IterationCount iterations, double cpu_time,
double num_threads) {
for (auto& c : *l) {

View File

@@ -12,29 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <string>
#include <tuple>
#include <vector>
#include "benchmark/benchmark.h"
#include "check.h"
#include "complexity.h"
#include "string_util.h"
#include "timers.h"
// File format reference: http://edoceo.com/utilitas/csv-file-format.
namespace benchmark {
namespace {
std::vector<std::string> elements = {
const std::vector<const char*> elements = {
"name", "iterations", "real_time", "cpu_time",
"time_unit", "bytes_per_second", "items_per_second", "label",
"error_occurred", "error_message"};
} // namespace
std::string CsvEscape(const std::string& s) {
std::string tmp;
@@ -51,6 +45,7 @@ std::string CsvEscape(const std::string& s) {
}
return '"' + tmp + '"';
}
} // namespace
BENCHMARK_EXPORT
bool CSVReporter::ReportContext(const Context& context) {

View File

@@ -36,6 +36,9 @@
// declarations of some other intrinsics, breaking compilation.
// Therefore, we simply declare __rdtsc ourselves. See also
// http://connect.microsoft.com/VisualStudio/feedback/details/262047
//
// Note that MSVC defines the x64 preprocessor macros when building
// for Arm64EC, despite it using Arm64 assembly instructions.
#if defined(COMPILER_MSVC) && !defined(_M_IX86) && !defined(_M_ARM64) && \
!defined(_M_ARM64EC)
extern "C" uint64_t __rdtsc();
@@ -79,7 +82,10 @@ inline BENCHMARK_ALWAYS_INLINE int64_t Now() {
int64_t ret;
__asm__ volatile("rdtsc" : "=A"(ret));
return ret;
#elif defined(__x86_64__) || defined(__amd64__)
// Note that Clang, like MSVC, defines the x64 preprocessor macros when building
// for Arm64EC, despite it using Arm64 assembly instructions.
#elif (defined(__x86_64__) || defined(__amd64__)) && !defined(__arm64ec__)
uint64_t low, high;
__asm__ volatile("rdtsc" : "=a"(low), "=d"(high));
return static_cast<int64_t>((high << 32) | low);
@@ -139,7 +145,7 @@ inline BENCHMARK_ALWAYS_INLINE int64_t Now() {
struct timespec ts = {0, 0};
clock_gettime(CLOCK_MONOTONIC, &ts);
return static_cast<int64_t>(ts.tv_sec) * 1000000000 + ts.tv_nsec;
#elif defined(__aarch64__)
#elif defined(__aarch64__) || defined(__arm64ec__)
// System timer of ARMv8 runs at a different frequency than the CPU's.
// The frequency is fixed, typically in the range 1-50MHz. It can be
// read at CNTFRQ special register. We assume the OS has set up

View File

@@ -106,6 +106,16 @@
#define BENCHMARK_MAYBE_UNUSED
#endif
#if defined(__GNUC__) || defined(__clang__)
#define PRINTF_FORMAT_STRING_FUNC(format_arg, first_idx) \
__attribute__((format(printf, format_arg, first_idx)))
#elif defined(__MINGW32__)
#define PRINTF_FORMAT_STRING_FUNC(format_arg, first_idx) \
__attribute__((format(__MINGW_PRINTF_FORMAT, format_arg, first_idx)))
#else
#define PRINTF_FORMAT_STRING_FUNC(format_arg, first_idx)
#endif
// clang-format on
#endif // BENCHMARK_INTERNAL_MACROS_H_

View File

@@ -81,7 +81,9 @@ std::string FormatKV(std::string const& key, bool value) {
std::string FormatKV(std::string const& key, int64_t value) {
std::stringstream ss;
ss << '"' << StrEscape(key) << "\": " << value;
// We really want to just dump the integer as-is,
// without the system locale interfering.
ss << '"' << StrEscape(key) << "\": " << std::to_string(value);
return ss.str();
}

View File

@@ -214,7 +214,7 @@ PerfCounters PerfCounters::Create(
// This should never happen but if it does, we give up on the
// entire batch as recovery would be a mess.
GetErrorLogInstance() << "***WARNING*** Failed to start counters. "
"Claring out all counters.\n";
"Clearing out all counters.\n";
// Close all performance counters
for (int id : counter_ids) {

View File

@@ -15,6 +15,8 @@
#ifndef BENCHMARK_RE_H_
#define BENCHMARK_RE_H_
#include <vector>
#include "internal_macros.h"
// clang-format off

View File

@@ -112,13 +112,14 @@ std::string ToBinaryStringFullySpecified(double value, int precision,
return mantissa + ExponentToPrefix(exponent, one_k == Counter::kIs1024);
}
PRINTF_FORMAT_STRING_FUNC(1, 0)
std::string StrFormatImp(const char* msg, va_list args) {
// we might need a second shot at this, so pre-emptivly make a copy
va_list args_cp;
va_copy(args_cp, args);
// TODO(ericwf): use std::array for first attempt to avoid one memory
// allocation guess what the size might be
// Use std::array for first attempt to avoid one memory allocation guess what
// the size might be
std::array<char, 256> local_buff = {};
// 2015-10-08: vsnprintf is used instead of snd::vsnprintf due to a limitation

View File

@@ -463,7 +463,7 @@ std::string GetSystemName() {
DWCOUNT, NULL, 0, NULL, NULL);
str.resize(len);
WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, hostname, DWCOUNT, &str[0],
str.size(), NULL, NULL);
static_cast<int>(str.size()), NULL, NULL);
#endif
return str;
#elif defined(BENCHMARK_OS_QURT)

View File

@@ -35,7 +35,7 @@ def copy_upstream_src(wpilib_root: Path):
def main():
name = "benchmark"
url = "https://github.com/google/benchmark.git"
tag = "v1.9.4"
tag = "v1.9.5"
benchmark = Lib(name, url, tag, copy_upstream_src)
benchmark.main()

View File

@@ -8,7 +8,7 @@ Subject: [PATCH 1/2] Add roboRIO benchmark support
1 file changed, 2 insertions(+)
diff --git a/src/sysinfo.cc b/src/sysinfo.cc
index 60e9e5c219a470944609f36773b4d8effa019059..86922c0da6303e1c35b4f7cb92a751fb84ba6f95 100644
index 3977772bfede4971379b157b5478abe7bdad21f7..ec52119ad73aca9c4667855e2f2fdbf4d22ced77 100644
--- a/src/sysinfo.cc
+++ b/src/sysinfo.cc
@@ -441,6 +441,8 @@ std::vector<CPUInfo::CacheInfo> GetCacheSizes() {

View File

@@ -43,10 +43,10 @@ index c90232f20ff7b6dfdc09ee2df02a6d735b1d99ea..c4c48d15a049f39c77aeee47ae46741e
return buff.get();
}
diff --git a/src/string_util.cc b/src/string_util.cc
index 420de4cf259ce0bf3087b004b1f0d0b1c78028a7..698129453cd6ea1baf5f12ae58db467008b6ce8c 100644
index 9c5df3ba25c92012bbae5063522a17bb47777151..9c483b335136a5b0e62c5f364a5eb1dfef5a414d 100644
--- a/src/string_util.cc
+++ b/src/string_util.cc
@@ -123,7 +123,14 @@ std::string StrFormatImp(const char* msg, va_list args) {
@@ -124,7 +124,14 @@ std::string StrFormatImp(const char* msg, va_list args) {
// 2015-10-08: vsnprintf is used instead of snd::vsnprintf due to a limitation
// in the android-ndk
@@ -61,7 +61,7 @@ index 420de4cf259ce0bf3087b004b1f0d0b1c78028a7..698129453cd6ea1baf5f12ae58db4670
va_end(args_cp);
@@ -141,7 +148,14 @@ std::string StrFormatImp(const char* msg, va_list args) {
@@ -142,7 +149,14 @@ std::string StrFormatImp(const char* msg, va_list args) {
auto buff_ptr = std::unique_ptr<char[]>(new char[size]);
// 2015-10-08: vsnprintf is used instead of snd::vsnprintf due to a limitation
// in the android-ndk