diff options
author | Anton Samokhvalov <pg83@yandex.ru> | 2022-02-10 16:45:15 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:15 +0300 |
commit | 72cb13b4aff9bc9cf22e49251bc8fd143f82538f (patch) | |
tree | da2c34829458c7d4e74bdfbdf85dff449e9e7fb8 /library/cpp/testing/benchmark | |
parent | 778e51ba091dc39e7b7fcab2b9cf4dbedfb6f2b5 (diff) | |
download | ydb-72cb13b4aff9bc9cf22e49251bc8fd143f82538f.tar.gz |
Restoring authorship annotation for Anton Samokhvalov <pg83@yandex.ru>. Commit 1 of 2.
Diffstat (limited to 'library/cpp/testing/benchmark')
-rw-r--r-- | library/cpp/testing/benchmark/bench.cpp | 648 | ||||
-rw-r--r-- | library/cpp/testing/benchmark/bench.h | 72 | ||||
-rw-r--r-- | library/cpp/testing/benchmark/examples/main.cpp | 332 | ||||
-rw-r--r-- | library/cpp/testing/benchmark/examples/ya.make | 12 | ||||
-rw-r--r-- | library/cpp/testing/benchmark/main/main.cpp | 6 | ||||
-rw-r--r-- | library/cpp/testing/benchmark/main/ya.make | 2 | ||||
-rw-r--r-- | library/cpp/testing/benchmark/ya.make | 6 |
7 files changed, 539 insertions, 539 deletions
diff --git a/library/cpp/testing/benchmark/bench.cpp b/library/cpp/testing/benchmark/bench.cpp index 08d8708005..be9bfbad3b 100644 --- a/library/cpp/testing/benchmark/bench.cpp +++ b/library/cpp/testing/benchmark/bench.cpp @@ -1,5 +1,5 @@ -#include "bench.h" - +#include "bench.h" + #include <contrib/libs/re2/re2/re2.h> #include <library/cpp/colorizer/output.h> @@ -7,287 +7,287 @@ #include <library/cpp/json/json_value.h> #include <library/cpp/linear_regression/linear_regression.h> #include <library/cpp/threading/poor_man_openmp/thread_helper.h> - -#include <util/system/hp_timer.h> + +#include <util/system/hp_timer.h> #include <util/system/info.h> -#include <util/stream/output.h> -#include <util/datetime/base.h> -#include <util/random/random.h> -#include <util/string/cast.h> -#include <util/generic/xrange.h> -#include <util/generic/algorithm.h> -#include <util/generic/singleton.h> -#include <util/system/spinlock.h> -#include <util/generic/function.h> -#include <util/generic/maybe.h> -#include <util/generic/strbuf.h> -#include <util/generic/intrlist.h> +#include <util/stream/output.h> +#include <util/datetime/base.h> +#include <util/random/random.h> +#include <util/string/cast.h> +#include <util/generic/xrange.h> +#include <util/generic/algorithm.h> +#include <util/generic/singleton.h> +#include <util/system/spinlock.h> +#include <util/generic/function.h> +#include <util/generic/maybe.h> +#include <util/generic/strbuf.h> +#include <util/generic/intrlist.h> #include <util/stream/format.h> -#include <util/system/yield.h> - +#include <util/system/yield.h> + using re2::RE2; -using namespace NBench; -using namespace NColorizer; -using namespace NLastGetopt; - -namespace { - struct TOptions { - double TimeBudget; - }; - - struct TResult { - TStringBuf TestName; - ui64 Samples; - ui64 Iterations; - TMaybe<double> CyclesPerIteration; - TMaybe<double> SecondsPerIteration; - double RunTime; +using namespace NBench; +using namespace NColorizer; +using namespace NLastGetopt; + +namespace { + struct TOptions { + double TimeBudget; + }; + + struct TResult { + TStringBuf TestName; + ui64 Samples; + ui64 Iterations; + TMaybe<double> CyclesPerIteration; + TMaybe<double> SecondsPerIteration; + double RunTime; size_t TestId; // Sequential test id (zero-based) - }; - - struct ITestRunner: public TIntrusiveListItem<ITestRunner> { + }; + + struct ITestRunner: public TIntrusiveListItem<ITestRunner> { virtual ~ITestRunner() = default; - void Register(); - - virtual TStringBuf Name() const noexcept = 0; - virtual TResult Run(const TOptions& opts) = 0; + void Register(); + + virtual TStringBuf Name() const noexcept = 0; + virtual TResult Run(const TOptions& opts) = 0; size_t SequentialId = 0; - }; - - struct TCpuBenchmark: public ITestRunner { - inline TCpuBenchmark(const char* name, NCpu::TUserFunc func) - : F(func) - , N(name) - { - Register(); - } - + }; + + struct TCpuBenchmark: public ITestRunner { + inline TCpuBenchmark(const char* name, NCpu::TUserFunc func) + : F(func) + , N(name) + { + Register(); + } + TResult Run(const TOptions& opts) override; - + TStringBuf Name() const noexcept override { - return N; - } - - std::function<NCpu::TUserFunc> F; - const TStringBuf N; - }; - + return N; + } + + std::function<NCpu::TUserFunc> F; + const TStringBuf N; + }; + inline TString DoFmtTime(double t) { - if (t > 0.1) { - return ToString(t) + " seconds"; - } - - t *= 1000.0; - - if (t > 0.1) { - return ToString(t) + " milliseconds"; - } - - t *= 1000.0; - - if (t > 0.1) { - return ToString(t) + " microseconds"; - } - - t *= 1000.0; - - if (t < 0.05) { - t = 0.0; - } - - return ToString(t) + " nanoseconds"; - } - - struct THiPerfTimer: public THPTimer { + if (t > 0.1) { + return ToString(t) + " seconds"; + } + + t *= 1000.0; + + if (t > 0.1) { + return ToString(t) + " milliseconds"; + } + + t *= 1000.0; + + if (t > 0.1) { + return ToString(t) + " microseconds"; + } + + t *= 1000.0; + + if (t < 0.05) { + t = 0.0; + } + + return ToString(t) + " nanoseconds"; + } + + struct THiPerfTimer: public THPTimer { static inline TString FmtTime(double t) { - return DoFmtTime(t); - } - }; - - struct TSimpleTimer { - inline double Passed() const noexcept { - return (TInstant::Now() - N).MicroSeconds() / 1000000.0; - } - + return DoFmtTime(t); + } + }; + + struct TSimpleTimer { + inline double Passed() const noexcept { + return (TInstant::Now() - N).MicroSeconds() / 1000000.0; + } + static inline TString FmtTime(double t) { - return DoFmtTime(t); - } - - const TInstant N = TInstant::Now(); - }; - - struct TCycleTimer { - inline ui64 Passed() const noexcept { - return GetCycleCount() - N; - } - + return DoFmtTime(t); + } + + const TInstant N = TInstant::Now(); + }; + + struct TCycleTimer { + inline ui64 Passed() const noexcept { + return GetCycleCount() - N; + } + static inline TString FmtTime(double t) { - if (t < 0.5) { - t = 0.0; - } - + if (t < 0.5) { + t = 0.0; + } + TString hr; if (t > 10 * 1000) { hr = " (" + ToString(HumanReadableSize(t, ESizeFormat::SF_QUANTITY)) + ")"; } return ToString(t) + hr + " cycles"; - } - - const ui64 N = GetCycleCount(); - }; - - template <class TMyTimer, class T> - inline double Measure(T&& t, size_t n) { - TMyTimer timer; - - t(n); - - return timer.Passed(); - } - - struct TSampleIterator { - inline size_t Next() noexcept { - return M++; - - N *= 1.02; - M += 1; - - return Max<double>(N, M); - } - - double N = 1.0; - size_t M = 1; - }; - - using TSample = std::pair<size_t, double>; + } + + const ui64 N = GetCycleCount(); + }; + + template <class TMyTimer, class T> + inline double Measure(T&& t, size_t n) { + TMyTimer timer; + + t(n); + + return timer.Passed(); + } + + struct TSampleIterator { + inline size_t Next() noexcept { + return M++; + + N *= 1.02; + M += 1; + + return Max<double>(N, M); + } + + double N = 1.0; + size_t M = 1; + }; + + using TSample = std::pair<size_t, double>; using TSamples = TVector<TSample>; - - struct TLinFunc { - double A; - double B; - - inline double operator()(double x) const noexcept { - return A * x + B; - } - }; - + + struct TLinFunc { + double A; + double B; + + inline double operator()(double x) const noexcept { + return A * x + B; + } + }; + TLinFunc CalcModel(const TSamples& s) { - TKahanSLRSolver solver; - - for (const auto& p : s) { - solver.Add(p.first, p.second); - } - - double c = 0; - double i = 0; - - solver.Solve(c, i); - - return TLinFunc{c, i}; - } - + TKahanSLRSolver solver; + + for (const auto& p : s) { + solver.Add(p.first, p.second); + } + + double c = 0; + double i = 0; + + solver.Solve(c, i); + + return TLinFunc{c, i}; + } + inline TSamples RemoveOutliers(const TSamples& s, double fraction) { if (s.size() < 20) { - return s; - } - - const auto predictor = CalcModel(s); - - const auto errfunc = [&predictor](const TSample& p) -> double { - //return (1.0 + fabs(predictor(p.first) - p.second)) / (1.0 + fabs(p.second)); - //return fabs((predictor(p.first) - p.second)) / (1.0 + fabs(p.second)); - //return fabs((predictor(p.first) - p.second)) / (1.0 + p.first); - return fabs((predictor(p.first) - p.second)); - }; - - using TSampleWithError = std::pair<const TSample*, double>; + return s; + } + + const auto predictor = CalcModel(s); + + const auto errfunc = [&predictor](const TSample& p) -> double { + //return (1.0 + fabs(predictor(p.first) - p.second)) / (1.0 + fabs(p.second)); + //return fabs((predictor(p.first) - p.second)) / (1.0 + fabs(p.second)); + //return fabs((predictor(p.first) - p.second)) / (1.0 + p.first); + return fabs((predictor(p.first) - p.second)); + }; + + using TSampleWithError = std::pair<const TSample*, double>; TVector<TSampleWithError> v; - + v.reserve(s.size()); - - for (const auto& p : s) { - v.emplace_back(&p, errfunc(p)); - } - - Sort(v.begin(), v.end(), [](const TSampleWithError& l, const TSampleWithError& r) -> bool { - return (l.second < r.second) || ((l.second == r.second) && (l.first < r.first)); - }); - - if (0) { - for (const auto& x : v) { - Cout << x.first->first << ", " << x.first->second << " -> " << x.second << Endl; - } - } - - TSamples ret; - + + for (const auto& p : s) { + v.emplace_back(&p, errfunc(p)); + } + + Sort(v.begin(), v.end(), [](const TSampleWithError& l, const TSampleWithError& r) -> bool { + return (l.second < r.second) || ((l.second == r.second) && (l.first < r.first)); + }); + + if (0) { + for (const auto& x : v) { + Cout << x.first->first << ", " << x.first->second << " -> " << x.second << Endl; + } + } + + TSamples ret; + ret.reserve(v.size()); - + for (const auto i : xrange<size_t>(0, fraction * v.size())) { - ret.push_back(*v[i].first); - } - - return ret; - } - - template <class TMyTimer, class T> - static inline TResult RunTest(T&& func, double budget, ITestRunner& test) { - THPTimer start; - - start.Passed(); - - TSampleIterator sample; - TSamples samples; - ui64 iters = 0; - - //warm up - func(1); - - while (start.Passed() < budget) { + ret.push_back(*v[i].first); + } + + return ret; + } + + template <class TMyTimer, class T> + static inline TResult RunTest(T&& func, double budget, ITestRunner& test) { + THPTimer start; + + start.Passed(); + + TSampleIterator sample; + TSamples samples; + ui64 iters = 0; + + //warm up + func(1); + + while (start.Passed() < budget) { if (start.Passed() < ((budget * samples.size()) / 2000000.0)) { - ThreadYield(); - } else { - const size_t n = sample.Next(); - - iters += (ui64)n; - samples.emplace_back(n, Measure<TMyTimer>(func, n)); - } - } - - auto filtered = RemoveOutliers(samples, 0.9); - + ThreadYield(); + } else { + const size_t n = sample.Next(); + + iters += (ui64)n; + samples.emplace_back(n, Measure<TMyTimer>(func, n)); + } + } + + auto filtered = RemoveOutliers(samples, 0.9); + return {test.Name(), filtered.size(), iters, CalcModel(filtered).A, Nothing(), start.Passed(), test.SequentialId}; - } - - using TTests = TIntrusiveListWithAutoDelete<ITestRunner, TDestructor>; - + } + + using TTests = TIntrusiveListWithAutoDelete<ITestRunner, TDestructor>; + inline TTests& Tests() { - return *Singleton<TTests>(); - } - - void ITestRunner::Register() { - Tests().PushBack(this); - } - - TResult TCpuBenchmark::Run(const TOptions& opts) { - return RunTest<TCycleTimer>([this](size_t n) { - NCpu::TParams params{n}; - - F(params); + return *Singleton<TTests>(); + } + + void ITestRunner::Register() { + Tests().PushBack(this); + } + + TResult TCpuBenchmark::Run(const TOptions& opts) { + return RunTest<TCycleTimer>([this](size_t n) { + NCpu::TParams params{n}; + + F(params); }, opts.TimeBudget, *this); - } + } enum EOutFormat { F_CONSOLE = 0 /* "console" */, - F_CSV /* "csv" */, - F_JSON /* "json" */ + F_CSV /* "csv" */, + F_JSON /* "json" */ }; TAdaptiveLock STDOUT_LOCK; - struct IReporter { + struct IReporter { virtual void Report(TResult&& result) = 0; virtual void Finish() { @@ -297,7 +297,7 @@ namespace { } }; - class TConsoleReporter: public IReporter { + class TConsoleReporter: public IReporter { public: ~TConsoleReporter() override { } @@ -309,7 +309,7 @@ namespace { } }; - class TCSVReporter: public IReporter { + class TCSVReporter: public IReporter { public: TCSVReporter() { Cout << "Name\tSamples\tIterations\tRun_time\tPer_iteration_sec\tPer_iteration_cycles" << Endl; @@ -344,7 +344,7 @@ namespace { } }; - class TJSONReporter: public IReporter { + class TJSONReporter: public IReporter { public: ~TJSONReporter() override { } @@ -427,15 +427,15 @@ namespace { case F_CSV: return MakeHolder<TCSVReporter>(); - + case F_JSON: return MakeHolder<TJSONReporter>(); - - default: - break; + + default: + break; } - - return MakeHolder<TConsoleReporter>(); // make compiler happy + + return MakeHolder<TConsoleReporter>(); // make compiler happy } THolder<IReporter> MakeOrderedReporter(const EOutFormat type) { @@ -447,12 +447,12 @@ namespace { tests[id]->SequentialId = id; } } -} +} template <> EOutFormat FromStringImpl<EOutFormat>(const char* data, size_t len) { const auto s = TStringBuf{data, len}; - + if (TStringBuf("console") == s) { return F_CONSOLE; } else if (TStringBuf("csv") == s) { @@ -462,55 +462,55 @@ EOutFormat FromStringImpl<EOutFormat>(const char* data, size_t len) { } ythrow TFromStringException{} << "failed to convert '" << s << '\''; -} - -template <> +} + +template <> void Out<TResult>(IOutputStream& out, const TResult& r) { - out << "----------- " << LightRed() << r.TestName << Old() << " ---------------" << Endl - << " samples: " << White() << r.Samples << Old() << Endl - << " iterations: " << White() << r.Iterations << Old() << Endl + out << "----------- " << LightRed() << r.TestName << Old() << " ---------------" << Endl + << " samples: " << White() << r.Samples << Old() << Endl + << " iterations: " << White() << r.Iterations << Old() << Endl << " iterations hr: " << White() << HumanReadableSize(r.Iterations, SF_QUANTITY) << Old() << Endl - << " run time: " << White() << r.RunTime << Old() << Endl; - - if (r.CyclesPerIteration) { - out << " per iteration: " << White() << TCycleTimer::FmtTime(*r.CyclesPerIteration) << Old() << Endl; - } - - if (r.SecondsPerIteration) { - out << " per iteration: " << White() << DoFmtTime(*r.SecondsPerIteration) << Old() << Endl; - } -} - -NCpu::TRegistar::TRegistar(const char* name, TUserFunc func) { + << " run time: " << White() << r.RunTime << Old() << Endl; + + if (r.CyclesPerIteration) { + out << " per iteration: " << White() << TCycleTimer::FmtTime(*r.CyclesPerIteration) << Old() << Endl; + } + + if (r.SecondsPerIteration) { + out << " per iteration: " << White() << DoFmtTime(*r.SecondsPerIteration) << Old() << Endl; + } +} + +NCpu::TRegistar::TRegistar(const char* name, TUserFunc func) { static_assert(sizeof(TCpuBenchmark) + alignof(TCpuBenchmark) < sizeof(Buf), "fix Buf size"); - + new (AlignUp(Buf, alignof(TCpuBenchmark))) TCpuBenchmark(name, func); -} - -namespace { - struct TProgOpts { - TProgOpts(int argc, char** argv) { - TOpts opts = TOpts::Default(); - - opts.AddHelpOption(); - - opts.AddLongOption('b', "budget") - .StoreResult(&TimeBudget) +} + +namespace { + struct TProgOpts { + TProgOpts(int argc, char** argv) { + TOpts opts = TOpts::Default(); + + opts.AddHelpOption(); + + opts.AddLongOption('b', "budget") + .StoreResult(&TimeBudget) .RequiredArgument("SEC") - .Optional() - .Help("overall time budget"); - - opts.AddLongOption('l', "list") + .Optional() + .Help("overall time budget"); + + opts.AddLongOption('l', "list") .NoArgument() .StoreValue(&ListTests, true) - .Help("list all tests"); - - opts.AddLongOption('t', "threads") - .StoreResult(&Threads) + .Help("list all tests"); + + opts.AddLongOption('t', "threads") + .StoreResult(&Threads) .OptionalValue(ToString((NSystemInfo::CachedNumberOfCpus() + 1) / 2), "JOBS") .DefaultValue("1") - .Help("run benchmarks in parallel"); - + .Help("run benchmarks in parallel"); + opts.AddLongOption('f', "format") .AddLongName("benchmark_format") .StoreResult(&OutFormat) @@ -521,18 +521,18 @@ namespace { opts.SetFreeArgDefaultTitle("REGEXP", "RE2 regular expression to filter tests"); const TOptsParseResult parseResult{&opts, argc, argv}; - + for (const auto& regexp : parseResult.GetFreeArgs()) { Filters.push_back(MakeHolder<RE2>(regexp.data(), RE2::Quiet)); Y_ENSURE(Filters.back()->ok(), "incorrect RE2 expression '" << regexp << "'"); } - } - - bool MatchFilters(const TStringBuf& name) const { - if (!Filters) { - return true; - } - + } + + bool MatchFilters(const TStringBuf& name) const { + if (!Filters) { + return true; + } + for (auto&& re : Filters) { if (RE2::FullMatchN({name.data(), name.size()}, *re, nullptr, 0)) { return true; @@ -542,50 +542,50 @@ namespace { return false; } - bool ListTests = false; - double TimeBudget = -1.0; + bool ListTests = false; + double TimeBudget = -1.0; TVector<THolder<RE2>> Filters; - size_t Threads = 0; + size_t Threads = 0; EOutFormat OutFormat; - }; -} - + }; +} + int NBench::Main(int argc, char** argv) { const TProgOpts opts(argc, argv); - + TVector<ITestRunner*> tests; for (auto&& it : Tests()) { if (opts.MatchFilters(it.Name())) { tests.push_back(&it); - } + } } EnumerateTests(tests); - + if (opts.ListTests) { for (const auto* const it : tests) { Cout << it->Name() << Endl; - } - + } + return 0; } - + if (!tests) { return 0; } - + double timeBudget = opts.TimeBudget; - + if (timeBudget < 0) { timeBudget = 5.0 * tests.size(); } - + const TOptions testOpts = {timeBudget / tests.size()}; const auto reporter = MakeOrderedReporter(opts.OutFormat); - - std::function<void(ITestRunner**)> func = [&](ITestRunner** it) { + + std::function<void(ITestRunner**)> func = [&](ITestRunner** it) { auto&& res = (*it)->Run(testOpts); - + reporter->Report(std::move(res)); }; @@ -596,9 +596,9 @@ int NBench::Main(int argc, char** argv) { for (auto it : tests) { func(&it); } - } + } reporter->Finish(); return 0; -} +} diff --git a/library/cpp/testing/benchmark/bench.h b/library/cpp/testing/benchmark/bench.h index 21551ad0dd..6f7a9f3f44 100644 --- a/library/cpp/testing/benchmark/bench.h +++ b/library/cpp/testing/benchmark/bench.h @@ -1,29 +1,29 @@ -#pragma once - +#pragma once + #include <util/system/compiler.h> -#include <util/system/types.h> - +#include <util/system/types.h> + #include <utility> -namespace NBench { - namespace NCpu { - struct TParams { - inline size_t Iterations() const noexcept { - return Iterations_; - } - - const size_t Iterations_; - }; - - using TUserFunc = void(TParams&); - - struct TRegistar { - TRegistar(const char* name, TUserFunc func); - - char Buf[128]; - }; - } - +namespace NBench { + namespace NCpu { + struct TParams { + inline size_t Iterations() const noexcept { + return Iterations_; + } + + const size_t Iterations_; + }; + + using TUserFunc = void(TParams&); + + struct TRegistar { + TRegistar(const char* name, TUserFunc func); + + char Buf[128]; + }; + } + /** * Functions that states "I can read and write everywhere in memory". * @@ -42,10 +42,10 @@ namespace NBench { #if defined(__GNUC__) Y_FORCE_INLINE void Clobber() { - asm volatile("" - : - : - : "memory"); + asm volatile("" + : + : + : "memory"); } #elif defined(_MSC_VER) Y_FORCE_INLINE void Clobber() { @@ -60,10 +60,10 @@ namespace NBench { #if defined(__GNUC__) template <typename T> Y_FORCE_INLINE void Escape(T* p) { - asm volatile("" - : - : "g"(p) - : "memory"); + asm volatile("" + : + : "g"(p) + : "memory"); } #else template <typename T> @@ -77,16 +77,16 @@ namespace NBench { * @param Unused variable (e.g. return value of benchmarked function). */ template <typename T> - Y_FORCE_INLINE void DoNotOptimize(T&& datum) { + Y_FORCE_INLINE void DoNotOptimize(T&& datum) { ::DoNotOptimizeAway(std::forward<T>(datum)); - } + } int Main(int argc, char** argv); -} - +} + #define Y_CPU_BENCHMARK(name, cnt) \ namespace N_bench_##name { \ static void Run(::NBench::NCpu::TParams&); \ const ::NBench::NCpu::TRegistar benchmark(#name, &Run); \ } \ - static void N_bench_##name::Run(::NBench::NCpu::TParams& cnt) + static void N_bench_##name::Run(::NBench::NCpu::TParams& cnt) diff --git a/library/cpp/testing/benchmark/examples/main.cpp b/library/cpp/testing/benchmark/examples/main.cpp index ddd8b05ffc..508d12111e 100644 --- a/library/cpp/testing/benchmark/examples/main.cpp +++ b/library/cpp/testing/benchmark/examples/main.cpp @@ -1,186 +1,186 @@ #include <library/cpp/testing/benchmark/bench.h> - -#include <util/generic/xrange.h> -#include <util/generic/algorithm.h> -#include <util/generic/vector.h> -#include <util/generic/yexception.h> -#include <util/generic/bt_exception.h> - -Y_CPU_BENCHMARK(F, iface) { + +#include <util/generic/xrange.h> +#include <util/generic/algorithm.h> +#include <util/generic/vector.h> +#include <util/generic/yexception.h> +#include <util/generic/bt_exception.h> + +Y_CPU_BENCHMARK(F, iface) { TVector<size_t> x; - - x.reserve(iface.Iterations()); - - for (size_t i = 0; i < iface.Iterations(); ++i) { - x.push_back(i); - } -} - -Y_CPU_BENCHMARK(EmptyF, iface) { - (void)iface; -} - -Y_CPU_BENCHMARK(AlmostEmptyF, iface) { - (void)iface; - + + x.reserve(iface.Iterations()); + + for (size_t i = 0; i < iface.Iterations(); ++i) { + x.push_back(i); + } +} + +Y_CPU_BENCHMARK(EmptyF, iface) { + (void)iface; +} + +Y_CPU_BENCHMARK(AlmostEmptyF, iface) { + (void)iface; + TVector<size_t> x; - x.resize(1); -} - -Y_CPU_BENCHMARK(TestThrow, iface) { - for (size_t i = 0; i < iface.Iterations(); ++i) { - try { - ythrow yexception() << i; - } catch (...) { - //CurrentExceptionMessage(); - } - } -} - -Y_CPU_BENCHMARK(TestThrowBT, iface) { - for (size_t i = 0; i < iface.Iterations(); ++i) { - try { - ythrow TWithBackTrace<yexception>() << i; - } catch (...) { - //CurrentExceptionMessage(); - } - } -} - -Y_CPU_BENCHMARK(TestThrowCatch, iface) { - for (size_t i = 0; i < iface.Iterations(); ++i) { - try { - ythrow yexception() << i; - } catch (...) { - Y_DO_NOT_OPTIMIZE_AWAY(CurrentExceptionMessage()); - } - } -} - -Y_CPU_BENCHMARK(TestThrowCatchBT, iface) { - for (size_t i = 0; i < iface.Iterations(); ++i) { - try { - ythrow TWithBackTrace<yexception>() << i; - } catch (...) { - Y_DO_NOT_OPTIMIZE_AWAY(CurrentExceptionMessage()); - } - } -} - -Y_CPU_BENCHMARK(TestRobust, iface) { - if (iface.Iterations() % 100 == 0) { - usleep(100000); - } -} - -Y_CPU_BENCHMARK(IterationSpeed, iface) { - const auto n = iface.Iterations(); - - for (size_t i = 0; i < n; ++i) { - Y_DO_NOT_OPTIMIZE_AWAY(i); - } -} - -Y_CPU_BENCHMARK(XRangeSpeed, iface) { - for (auto i : xrange<size_t>(0, iface.Iterations())) { - Y_DO_NOT_OPTIMIZE_AWAY(i); - } -} - -Y_NO_INLINE int FFF() { - return 0; -} - -Y_NO_INLINE int FFF(int x) { - return x; -} - -Y_NO_INLINE int FFF(int x, int y) { - return x + y; -} - -Y_NO_INLINE size_t FS1(TStringBuf x) { + x.resize(1); +} + +Y_CPU_BENCHMARK(TestThrow, iface) { + for (size_t i = 0; i < iface.Iterations(); ++i) { + try { + ythrow yexception() << i; + } catch (...) { + //CurrentExceptionMessage(); + } + } +} + +Y_CPU_BENCHMARK(TestThrowBT, iface) { + for (size_t i = 0; i < iface.Iterations(); ++i) { + try { + ythrow TWithBackTrace<yexception>() << i; + } catch (...) { + //CurrentExceptionMessage(); + } + } +} + +Y_CPU_BENCHMARK(TestThrowCatch, iface) { + for (size_t i = 0; i < iface.Iterations(); ++i) { + try { + ythrow yexception() << i; + } catch (...) { + Y_DO_NOT_OPTIMIZE_AWAY(CurrentExceptionMessage()); + } + } +} + +Y_CPU_BENCHMARK(TestThrowCatchBT, iface) { + for (size_t i = 0; i < iface.Iterations(); ++i) { + try { + ythrow TWithBackTrace<yexception>() << i; + } catch (...) { + Y_DO_NOT_OPTIMIZE_AWAY(CurrentExceptionMessage()); + } + } +} + +Y_CPU_BENCHMARK(TestRobust, iface) { + if (iface.Iterations() % 100 == 0) { + usleep(100000); + } +} + +Y_CPU_BENCHMARK(IterationSpeed, iface) { + const auto n = iface.Iterations(); + + for (size_t i = 0; i < n; ++i) { + Y_DO_NOT_OPTIMIZE_AWAY(i); + } +} + +Y_CPU_BENCHMARK(XRangeSpeed, iface) { + for (auto i : xrange<size_t>(0, iface.Iterations())) { + Y_DO_NOT_OPTIMIZE_AWAY(i); + } +} + +Y_NO_INLINE int FFF() { + return 0; +} + +Y_NO_INLINE int FFF(int x) { + return x; +} + +Y_NO_INLINE int FFF(int x, int y) { + return x + y; +} + +Y_NO_INLINE size_t FS1(TStringBuf x) { return x.size(); -} - -Y_NO_INLINE size_t FS1_2(TStringBuf x, TStringBuf y) { +} + +Y_NO_INLINE size_t FS1_2(TStringBuf x, TStringBuf y) { return x.size() + y.size(); -} - -Y_NO_INLINE size_t FS2(const TStringBuf& x) { +} + +Y_NO_INLINE size_t FS2(const TStringBuf& x) { return x.size(); -} - -Y_NO_INLINE size_t FS2_2(const TStringBuf& x, const TStringBuf& y) { +} + +Y_NO_INLINE size_t FS2_2(const TStringBuf& x, const TStringBuf& y) { return x.size() + y.size(); -} - -Y_CPU_BENCHMARK(FunctionCallCost_StringBufVal1, iface) { - TStringBuf x; - - for (auto i : xrange<size_t>(0, iface.Iterations())) { - (void)i; +} + +Y_CPU_BENCHMARK(FunctionCallCost_StringBufVal1, iface) { + TStringBuf x; + + for (auto i : xrange<size_t>(0, iface.Iterations())) { + (void)i; NBench::Escape(&x); - Y_DO_NOT_OPTIMIZE_AWAY(FS1(x)); + Y_DO_NOT_OPTIMIZE_AWAY(FS1(x)); NBench::Clobber(); - } -} - -Y_CPU_BENCHMARK(FunctionCallCost_StringBufRef1, iface) { - TStringBuf x; - - for (auto i : xrange<size_t>(0, iface.Iterations())) { - (void)i; + } +} + +Y_CPU_BENCHMARK(FunctionCallCost_StringBufRef1, iface) { + TStringBuf x; + + for (auto i : xrange<size_t>(0, iface.Iterations())) { + (void)i; NBench::Escape(&x); - Y_DO_NOT_OPTIMIZE_AWAY(FS2(x)); + Y_DO_NOT_OPTIMIZE_AWAY(FS2(x)); NBench::Clobber(); - } -} - -Y_CPU_BENCHMARK(FunctionCallCost_StringBufVal2, iface) { - TStringBuf x; - TStringBuf y; - - for (auto i : xrange<size_t>(0, iface.Iterations())) { - (void)i; + } +} + +Y_CPU_BENCHMARK(FunctionCallCost_StringBufVal2, iface) { + TStringBuf x; + TStringBuf y; + + for (auto i : xrange<size_t>(0, iface.Iterations())) { + (void)i; NBench::Escape(&x); NBench::Escape(&y); - Y_DO_NOT_OPTIMIZE_AWAY(FS1_2(x, y)); + Y_DO_NOT_OPTIMIZE_AWAY(FS1_2(x, y)); NBench::Clobber(); - } -} - -Y_CPU_BENCHMARK(FunctionCallCost_StringBufRef2, iface) { - TStringBuf x; - TStringBuf y; - - for (auto i : xrange<size_t>(0, iface.Iterations())) { - (void)i; + } +} + +Y_CPU_BENCHMARK(FunctionCallCost_StringBufRef2, iface) { + TStringBuf x; + TStringBuf y; + + for (auto i : xrange<size_t>(0, iface.Iterations())) { + (void)i; NBench::Escape(&x); NBench::Escape(&y); - Y_DO_NOT_OPTIMIZE_AWAY(FS2_2(x, y)); + Y_DO_NOT_OPTIMIZE_AWAY(FS2_2(x, y)); NBench::Clobber(); - } -} - -Y_CPU_BENCHMARK(FunctionCallCost_NoArg, iface) { - for (auto i : xrange<size_t>(0, iface.Iterations())) { - (void)i; - Y_DO_NOT_OPTIMIZE_AWAY(FFF()); - } -} - -Y_CPU_BENCHMARK(FunctionCallCost_OneArg, iface) { - for (auto i : xrange<size_t>(0, iface.Iterations())) { - Y_DO_NOT_OPTIMIZE_AWAY(FFF(i)); - } -} - -Y_CPU_BENCHMARK(FunctionCallCost_TwoArg, iface) { - for (auto i : xrange<size_t>(0, iface.Iterations())) { - Y_DO_NOT_OPTIMIZE_AWAY(FFF(i, i)); - } -} + } +} + +Y_CPU_BENCHMARK(FunctionCallCost_NoArg, iface) { + for (auto i : xrange<size_t>(0, iface.Iterations())) { + (void)i; + Y_DO_NOT_OPTIMIZE_AWAY(FFF()); + } +} + +Y_CPU_BENCHMARK(FunctionCallCost_OneArg, iface) { + for (auto i : xrange<size_t>(0, iface.Iterations())) { + Y_DO_NOT_OPTIMIZE_AWAY(FFF(i)); + } +} + +Y_CPU_BENCHMARK(FunctionCallCost_TwoArg, iface) { + for (auto i : xrange<size_t>(0, iface.Iterations())) { + Y_DO_NOT_OPTIMIZE_AWAY(FFF(i, i)); + } +} /* An example of incorrect benchmark. As of r2581591 Clang 3.7 produced following assembly: * @code diff --git a/library/cpp/testing/benchmark/examples/ya.make b/library/cpp/testing/benchmark/examples/ya.make index 7e696e127a..c5c435ce10 100644 --- a/library/cpp/testing/benchmark/examples/ya.make +++ b/library/cpp/testing/benchmark/examples/ya.make @@ -4,9 +4,9 @@ OWNER( ) Y_BENCHMARK() - -SRCS( - main.cpp -) - -END() + +SRCS( + main.cpp +) + +END() diff --git a/library/cpp/testing/benchmark/main/main.cpp b/library/cpp/testing/benchmark/main/main.cpp index aabcb89c43..3ef4a4f348 100644 --- a/library/cpp/testing/benchmark/main/main.cpp +++ b/library/cpp/testing/benchmark/main/main.cpp @@ -8,9 +8,9 @@ int main(int argc, char** argv) { try { return NBench::Main(argc, argv); - } catch (...) { + } catch (...) { Cerr << CurrentExceptionMessage() << Endl; } - - return EXIT_FAILURE; + + return EXIT_FAILURE; } diff --git a/library/cpp/testing/benchmark/main/ya.make b/library/cpp/testing/benchmark/main/ya.make index d00cdcf9fc..9a088cfcea 100644 --- a/library/cpp/testing/benchmark/main/ya.make +++ b/library/cpp/testing/benchmark/main/ya.make @@ -6,7 +6,7 @@ OWNER( ) SRCS( - GLOBAL main.cpp + GLOBAL main.cpp ) PEERDIR( diff --git a/library/cpp/testing/benchmark/ya.make b/library/cpp/testing/benchmark/ya.make index f42be80698..a2c23a50fb 100644 --- a/library/cpp/testing/benchmark/ya.make +++ b/library/cpp/testing/benchmark/ya.make @@ -1,12 +1,12 @@ -LIBRARY() - +LIBRARY() + OWNER( pg yazevnul ) SRCS( - bench.cpp + bench.cpp dummy.cpp ) |