diff options
author | robot-contrib <robot-contrib@yandex-team.com> | 2023-09-01 21:19:54 +0300 |
---|---|---|
committer | robot-contrib <robot-contrib@yandex-team.com> | 2023-09-01 21:35:12 +0300 |
commit | 8cdb17329e895b47a6d1b9c3b4a7c3656e27e83e (patch) | |
tree | 4308e8581775082155da6254d80946d4b1de686e | |
parent | 9328299988a7a924459808b2ec896db5939038af (diff) | |
download | ydb-8cdb17329e895b47a6d1b9c3b4a7c3656e27e83e.tar.gz |
Update contrib/restricted/google/benchmark to 1.8.3
10 files changed, 112 insertions, 61 deletions
diff --git a/contrib/restricted/google/benchmark/AUTHORS b/contrib/restricted/google/benchmark/AUTHORS index bafecaddb5..d08c1fdb87 100644 --- a/contrib/restricted/google/benchmark/AUTHORS +++ b/contrib/restricted/google/benchmark/AUTHORS @@ -28,6 +28,7 @@ Eric Backus <eric_backus@alum.mit.edu> Eric Fiselier <eric@efcs.ca> Eugene Zhuk <eugene.zhuk@gmail.com> Evgeny Safronov <division494@gmail.com> +Fabien Pichot <pichot.fabien@gmail.com> Federico Ficarelli <federico.ficarelli@gmail.com> Felix Homann <linuxaudio@showlabor.de> Gergő Szitár <szitar.gergo@gmail.com> @@ -47,14 +48,15 @@ Marcel Jacobse <mjacobse@uni-bremen.de> Matt Clarkson <mattyclarkson@gmail.com> Maxim Vafin <maxvafin@gmail.com> Mike Apodaca <gatorfax@gmail.com> +Min-Yih Hsu <yihshyng223@gmail.com> MongoDB Inc. Nick Hutchinson <nshutchinson@gmail.com> Norman Heino <norman.heino@gmail.com> Oleksandr Sochka <sasha.sochka@gmail.com> Ori Livneh <ori.livneh@gmail.com> Paul Redmond <paul.redmond@gmail.com> -Raghu Raja <raghu@enfabrica.net> Radoslav Yovchev <radoslav.tm@gmail.com> +Raghu Raja <raghu@enfabrica.net> Rainer Orth <ro@cebitec.uni-bielefeld.de> Roman Lebedev <lebedev.ri@gmail.com> Sayan Bhattacharjee <aero.sayan@gmail.com> @@ -67,4 +69,3 @@ Tobias Schmidt <tobias.schmidt@in.tum.de> Yixuan Qiu <yixuanq@gmail.com> Yusuke Suzuki <utatane.tea@gmail.com> Zbigniew Skowron <zbychs@gmail.com> -Min-Yih Hsu <yihshyng223@gmail.com> diff --git a/contrib/restricted/google/benchmark/src/benchmark.cc b/contrib/restricted/google/benchmark/src/benchmark.cc index 7fb1740af3..6139e59d05 100644 --- a/contrib/restricted/google/benchmark/src/benchmark.cc +++ b/contrib/restricted/google/benchmark/src/benchmark.cc @@ -179,6 +179,17 @@ State::State(std::string name, IterationCount max_iters, BM_CHECK_LT(thread_index_, threads_) << "thread_index must be less than threads"; + // Add counters with correct flag now. If added with `counters[name]` in + // `PauseTiming`, a new `Counter` will be inserted the first time, which + // won't have the flag. Inserting them now also reduces the allocations + // during the benchmark. + if (perf_counters_measurement_) { + for (const std::string& counter_name : + perf_counters_measurement_->names()) { + counters[counter_name] = Counter(0.0, Counter::kAvgIterations); + } + } + // Note: The use of offsetof below is technically undefined until C++17 // because State is not a standard layout type. However, all compilers // currently provide well-defined behavior as an extension (which is @@ -227,10 +238,11 @@ void State::PauseTiming() { BM_CHECK(false) << "Perf counters read the value failed."; } for (const auto& name_and_measurement : measurements) { - auto name = name_and_measurement.first; - auto measurement = name_and_measurement.second; - BM_CHECK_EQ(std::fpclassify(double{counters[name]}), FP_ZERO); - counters[name] = Counter(measurement, Counter::kAvgIterations); + const std::string& name = name_and_measurement.first; + const double measurement = name_and_measurement.second; + // Counter was inserted with `kAvgIterations` flag by the constructor. + assert(counters.find(name) != counters.end()); + counters[name].value += measurement; } } } @@ -384,7 +396,7 @@ void RunBenchmarks(const std::vector<BenchmarkInstance>& benchmarks, BenchmarkReporter::PerFamilyRunReports* reports_for_family = nullptr; if (benchmark.complexity() != oNone) reports_for_family = &per_family_reports[benchmark.family_index()]; - benchmarks_with_threads += (benchmark.threads() > 0); + benchmarks_with_threads += (benchmark.threads() > 1); runners.emplace_back(benchmark, &perfcounters, reports_for_family); int num_repeats_of_this_instance = runners.back().GetNumRepeats(); num_repetitions_total += num_repeats_of_this_instance; @@ -575,7 +587,9 @@ size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, } if (!file_reporter) { default_file_reporter = internal::CreateReporter( - FLAGS_benchmark_out_format, ConsoleReporter::OO_None); + FLAGS_benchmark_out_format, FLAGS_benchmark_counters_tabular + ? ConsoleReporter::OO_Tabular + : ConsoleReporter::OO_None); file_reporter = default_file_reporter.get(); } file_reporter->SetOutputStream(&output_file); diff --git a/contrib/restricted/google/benchmark/src/perf_counters.cc b/contrib/restricted/google/benchmark/src/perf_counters.cc index 5f2ac282ab..9f564b46bb 100644 --- a/contrib/restricted/google/benchmark/src/perf_counters.cc +++ b/contrib/restricted/google/benchmark/src/perf_counters.cc @@ -57,9 +57,18 @@ size_t PerfCounterValues::Read(const std::vector<int>& leaders) { const bool PerfCounters::kSupported = true; -bool PerfCounters::Initialize() { return pfm_initialize() == PFM_SUCCESS; } +// Initializes libpfm only on the first call. Returns whether that single +// initialization was successful. +bool PerfCounters::Initialize() { + // Function-scope static gets initialized only once on first call. + static const bool success = []() { + return pfm_initialize() == PFM_SUCCESS; + }(); + return success; +} bool PerfCounters::IsCounterSupported(const std::string& name) { + Initialize(); perf_event_attr_t attr; std::memset(&attr, 0, sizeof(attr)); pfm_perf_encode_arg_t arg; @@ -73,6 +82,10 @@ bool PerfCounters::IsCounterSupported(const std::string& name) { PerfCounters PerfCounters::Create( const std::vector<std::string>& counter_names) { + if (!counter_names.empty()) { + Initialize(); + } + // Valid counters will populate these arrays but we start empty std::vector<std::string> valid_names; std::vector<int> counter_ids; diff --git a/contrib/restricted/google/benchmark/src/perf_counters.h b/contrib/restricted/google/benchmark/src/perf_counters.h index 152a6f2561..bf5eb6bc3a 100644 --- a/contrib/restricted/google/benchmark/src/perf_counters.h +++ b/contrib/restricted/google/benchmark/src/perf_counters.h @@ -190,8 +190,6 @@ class BENCHMARK_EXPORT PerfCountersMeasurement final { PerfCounterValues end_values_; }; -BENCHMARK_UNUSED static bool perf_init_anchor = PerfCounters::Initialize(); - } // namespace internal } // namespace benchmark diff --git a/contrib/restricted/google/benchmark/src/statistics.cc b/contrib/restricted/google/benchmark/src/statistics.cc index c4b54b271f..844e926895 100644 --- a/contrib/restricted/google/benchmark/src/statistics.cc +++ b/contrib/restricted/google/benchmark/src/statistics.cc @@ -42,13 +42,13 @@ double StatisticsMedian(const std::vector<double>& v) { auto center = copy.begin() + v.size() / 2; std::nth_element(copy.begin(), center, copy.end()); - // did we have an odd number of samples? - // if yes, then center is the median - // it no, then we are looking for the average between center and the value - // before + // Did we have an odd number of samples? If yes, then center is the median. + // If not, then we are looking for the average between center and the value + // before. Instead of resorting, we just look for the max value before it, + // which is not necessarily the element immediately preceding `center` Since + // `copy` is only partially sorted by `nth_element`. if (v.size() % 2 == 1) return *center; - auto center2 = copy.begin() + v.size() / 2 - 1; - std::nth_element(copy.begin(), center2, copy.end()); + auto center2 = std::max_element(copy.begin(), center); return (*center + *center2) / 2.0; } diff --git a/contrib/restricted/google/benchmark/src/string_util.cc b/contrib/restricted/google/benchmark/src/string_util.cc index 5e2d24a3cd..c69e40a813 100644 --- a/contrib/restricted/google/benchmark/src/string_util.cc +++ b/contrib/restricted/google/benchmark/src/string_util.cc @@ -11,16 +11,17 @@ #include <sstream> #include "arraysize.h" +#include "benchmark/benchmark.h" namespace benchmark { namespace { - // kilo, Mega, Giga, Tera, Peta, Exa, Zetta, Yotta. -const char kBigSIUnits[] = "kMGTPEZY"; +const char* const kBigSIUnits[] = {"k", "M", "G", "T", "P", "E", "Z", "Y"}; // Kibi, Mebi, Gibi, Tebi, Pebi, Exbi, Zebi, Yobi. -const char kBigIECUnits[] = "KMGTPEZY"; +const char* const kBigIECUnits[] = {"Ki", "Mi", "Gi", "Ti", + "Pi", "Ei", "Zi", "Yi"}; // milli, micro, nano, pico, femto, atto, zepto, yocto. -const char kSmallSIUnits[] = "munpfazy"; +const char* const kSmallSIUnits[] = {"m", "u", "n", "p", "f", "a", "z", "y"}; // We require that all three arrays have the same size. static_assert(arraysize(kBigSIUnits) == arraysize(kBigIECUnits), @@ -30,9 +31,8 @@ static_assert(arraysize(kSmallSIUnits) == arraysize(kBigSIUnits), static const int64_t kUnitsSize = arraysize(kBigSIUnits); -void ToExponentAndMantissa(double val, double thresh, int precision, - double one_k, std::string* mantissa, - int64_t* exponent) { +void ToExponentAndMantissa(double val, int precision, double one_k, + std::string* mantissa, int64_t* exponent) { std::stringstream mantissa_stream; if (val < 0) { @@ -43,8 +43,8 @@ void ToExponentAndMantissa(double val, double thresh, int precision, // Adjust threshold so that it never excludes things which can't be rendered // in 'precision' digits. const double adjusted_threshold = - std::max(thresh, 1.0 / std::pow(10.0, precision)); - const double big_threshold = adjusted_threshold * one_k; + std::max(1.0, 1.0 / std::pow(10.0, precision)); + const double big_threshold = (adjusted_threshold * one_k) - 1; const double small_threshold = adjusted_threshold; // Values in ]simple_threshold,small_threshold[ will be printed as-is const double simple_threshold = 0.01; @@ -92,37 +92,20 @@ std::string ExponentToPrefix(int64_t exponent, bool iec) { const int64_t index = (exponent > 0 ? exponent - 1 : -exponent - 1); if (index >= kUnitsSize) return ""; - const char* array = + const char* const* array = (exponent > 0 ? (iec ? kBigIECUnits : kBigSIUnits) : kSmallSIUnits); - if (iec) { - return array[index] + std::string("i"); - } - return std::string(1, array[index]); + + return std::string(array[index]); } -std::string ToBinaryStringFullySpecified(double value, double threshold, - int precision, double one_k = 1024.0) { +std::string ToBinaryStringFullySpecified(double value, int precision, + Counter::OneK one_k) { std::string mantissa; int64_t exponent; - ToExponentAndMantissa(value, threshold, precision, one_k, &mantissa, + ToExponentAndMantissa(value, precision, + one_k == Counter::kIs1024 ? 1024.0 : 1000.0, &mantissa, &exponent); - return mantissa + ExponentToPrefix(exponent, false); -} - -} // end namespace - -void AppendHumanReadable(int n, std::string* str) { - std::stringstream ss; - // Round down to the nearest SI prefix. - ss << ToBinaryStringFullySpecified(n, 1.0, 0); - *str += ss.str(); -} - -std::string HumanReadableNumber(double n, double one_k) { - // 1.1 means that figures up to 1.1k should be shown with the next unit down; - // this softens edge effects. - // 1 means that we should show one decimal place of precision. - return ToBinaryStringFullySpecified(n, 1.1, 1, one_k); + return mantissa + ExponentToPrefix(exponent, one_k == Counter::kIs1024); } std::string StrFormatImp(const char* msg, va_list args) { @@ -155,6 +138,12 @@ std::string StrFormatImp(const char* msg, va_list args) { return std::string(buff_ptr.get()); } +} // end namespace + +std::string HumanReadableNumber(double n, Counter::OneK one_k) { + return ToBinaryStringFullySpecified(n, 1, one_k); +} + std::string StrFormat(const char* format, ...) { va_list args; va_start(args, format); diff --git a/contrib/restricted/google/benchmark/src/string_util.h b/contrib/restricted/google/benchmark/src/string_util.h index 37bdd2e980..731aa2c04c 100644 --- a/contrib/restricted/google/benchmark/src/string_util.h +++ b/contrib/restricted/google/benchmark/src/string_util.h @@ -6,15 +6,15 @@ #include <utility> #include <vector> +#include "benchmark/benchmark.h" #include "benchmark/export.h" #include "check.h" #include "internal_macros.h" namespace benchmark { -void AppendHumanReadable(int n, std::string* str); - -std::string HumanReadableNumber(double n, double one_k = 1024.0); +BENCHMARK_EXPORT +std::string HumanReadableNumber(double n, Counter::OneK one_k); BENCHMARK_EXPORT #if defined(__MINGW32__) diff --git a/contrib/restricted/google/benchmark/src/sysinfo.cc b/contrib/restricted/google/benchmark/src/sysinfo.cc index 80eece3ae7..010bec78e1 100644 --- a/contrib/restricted/google/benchmark/src/sysinfo.cc +++ b/contrib/restricted/google/benchmark/src/sysinfo.cc @@ -328,7 +328,7 @@ std::vector<CPUInfo::CacheInfo> GetCacheSizesWindows() { using UPtr = std::unique_ptr<PInfo, decltype(&std::free)>; GetLogicalProcessorInformation(nullptr, &buffer_size); - UPtr buff((PInfo*)malloc(buffer_size), &std::free); + UPtr buff(static_cast<PInfo*>(std::malloc(buffer_size)), &std::free); if (!GetLogicalProcessorInformation(buff.get(), &buffer_size)) PrintErrorAndDie("Failed during call to GetLogicalProcessorInformation: ", GetLastError()); @@ -738,8 +738,8 @@ double GetCPUCyclesPerSecond(CPUInfo::Scaling scaling) { SHGetValueA(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", "~MHz", nullptr, &data, &data_size))) - return static_cast<double>((int64_t)data * - (int64_t)(1000 * 1000)); // was mhz + return static_cast<double>(static_cast<int64_t>(data) * + static_cast<int64_t>(1000 * 1000)); // was mhz #elif defined(BENCHMARK_OS_SOLARIS) kstat_ctl_t* kc = kstat_open(); if (!kc) { @@ -817,7 +817,7 @@ std::vector<double> GetLoadAvg() { #if (defined BENCHMARK_OS_FREEBSD || defined(BENCHMARK_OS_LINUX) || \ defined BENCHMARK_OS_MACOSX || defined BENCHMARK_OS_NETBSD || \ defined BENCHMARK_OS_OPENBSD || defined BENCHMARK_OS_DRAGONFLY) && \ - !defined(__ANDROID__) + !(defined(__ANDROID__) && __ANDROID_API__ < 29) static constexpr int kMaxSamples = 3; std::vector<double> res(kMaxSamples, 0.0); const int nelem = getloadavg(res.data(), kMaxSamples); diff --git a/contrib/restricted/google/benchmark/test/string_util_gtest.cc b/contrib/restricted/google/benchmark/test/string_util_gtest.cc index 8bfdb7a72c..67b4bc0c24 100644 --- a/contrib/restricted/google/benchmark/test/string_util_gtest.cc +++ b/contrib/restricted/google/benchmark/test/string_util_gtest.cc @@ -1,11 +1,12 @@ //===---------------------------------------------------------------------===// -// statistics_test - Unit tests for src/statistics.cc +// string_util_test - Unit tests for src/string_util.cc //===---------------------------------------------------------------------===// #include <tuple> #include "../src/internal_macros.h" #include "../src/string_util.h" +#include "gmock/gmock.h" #include "gtest/gtest.h" namespace { @@ -160,4 +161,39 @@ TEST(StringUtilTest, StrSplit) { std::vector<std::string>({"hello", "there", "is", "more"})); } +using HumanReadableFixture = ::testing::TestWithParam< + std::tuple<double, benchmark::Counter::OneK, std::string>>; + +INSTANTIATE_TEST_SUITE_P( + HumanReadableTests, HumanReadableFixture, + ::testing::Values( + std::make_tuple(0.0, benchmark::Counter::kIs1024, "0"), + std::make_tuple(999.0, benchmark::Counter::kIs1024, "999"), + std::make_tuple(1000.0, benchmark::Counter::kIs1024, "1000"), + std::make_tuple(1024.0, benchmark::Counter::kIs1024, "1Ki"), + std::make_tuple(1000 * 1000.0, benchmark::Counter::kIs1024, + "976\\.56.Ki"), + std::make_tuple(1024 * 1024.0, benchmark::Counter::kIs1024, "1Mi"), + std::make_tuple(1000 * 1000 * 1000.0, benchmark::Counter::kIs1024, + "953\\.674Mi"), + std::make_tuple(1024 * 1024 * 1024.0, benchmark::Counter::kIs1024, + "1Gi"), + std::make_tuple(0.0, benchmark::Counter::kIs1000, "0"), + std::make_tuple(999.0, benchmark::Counter::kIs1000, "999"), + std::make_tuple(1000.0, benchmark::Counter::kIs1000, "1k"), + std::make_tuple(1024.0, benchmark::Counter::kIs1000, "1.024k"), + std::make_tuple(1000 * 1000.0, benchmark::Counter::kIs1000, "1M"), + std::make_tuple(1024 * 1024.0, benchmark::Counter::kIs1000, + "1\\.04858M"), + std::make_tuple(1000 * 1000 * 1000.0, benchmark::Counter::kIs1000, + "1G"), + std::make_tuple(1024 * 1024 * 1024.0, benchmark::Counter::kIs1000, + "1\\.07374G"))); + +TEST_P(HumanReadableFixture, HumanReadableNumber) { + std::string str = benchmark::HumanReadableNumber(std::get<0>(GetParam()), + std::get<1>(GetParam())); + ASSERT_THAT(str, ::testing::MatchesRegex(std::get<2>(GetParam()))); +} + } // end namespace diff --git a/contrib/restricted/google/benchmark/ya.make b/contrib/restricted/google/benchmark/ya.make index c3e8191cea..28b94b3576 100644 --- a/contrib/restricted/google/benchmark/ya.make +++ b/contrib/restricted/google/benchmark/ya.make @@ -6,9 +6,9 @@ LICENSE(Apache-2.0) LICENSE_TEXTS(.yandex_meta/licenses.list.txt) -VERSION(1.8.2) +VERSION(1.8.3) -ORIGINAL_SOURCE(https://github.com/google/benchmark/archive/v1.8.2.tar.gz) +ORIGINAL_SOURCE(https://github.com/google/benchmark/archive/v1.8.3.tar.gz) ADDINCL( GLOBAL contrib/restricted/google/benchmark/include |