aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/testing/benchmark
diff options
context:
space:
mode:
authorAnton Samokhvalov <pg83@yandex.ru>2022-02-10 16:45:17 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:17 +0300
commitd3a398281c6fd1d3672036cb2d63f842d2cb28c5 (patch)
treedd4bd3ca0f36b817e96812825ffaf10d645803f2 /library/cpp/testing/benchmark
parent72cb13b4aff9bc9cf22e49251bc8fd143f82538f (diff)
downloadydb-d3a398281c6fd1d3672036cb2d63f842d2cb28c5.tar.gz
Restoring authorship annotation for Anton Samokhvalov <pg83@yandex.ru>. Commit 2 of 2.
Diffstat (limited to 'library/cpp/testing/benchmark')
-rw-r--r--library/cpp/testing/benchmark/bench.cpp648
-rw-r--r--library/cpp/testing/benchmark/bench.h72
-rw-r--r--library/cpp/testing/benchmark/examples/main.cpp332
-rw-r--r--library/cpp/testing/benchmark/examples/ya.make12
-rw-r--r--library/cpp/testing/benchmark/main/main.cpp6
-rw-r--r--library/cpp/testing/benchmark/main/ya.make2
-rw-r--r--library/cpp/testing/benchmark/ya.make6
7 files changed, 539 insertions, 539 deletions
diff --git a/library/cpp/testing/benchmark/bench.cpp b/library/cpp/testing/benchmark/bench.cpp
index be9bfbad3b..08d8708005 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 6f7a9f3f44..21551ad0dd 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 508d12111e..ddd8b05ffc 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 c5c435ce10..7e696e127a 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 3ef4a4f348..aabcb89c43 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 9a088cfcea..d00cdcf9fc 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 a2c23a50fb..f42be80698 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
)