diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..1dac57f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "editor.defaultFormatter": "xaver.clang-format", + "editor.formatOnSave": true +} \ No newline at end of file diff --git a/bench/main.cc b/bench/main.cc index d0d5caf..3623c28 100644 --- a/bench/main.cc +++ b/bench/main.cc @@ -94,23 +94,35 @@ static void BM_taylor_atomic_upd(benchmark::State& state) { } } -void updValue(double res, const std::string& key) { +void updMapValue(double res, const std::string& key) { static std::unordered_map d = {{"key", 10.0}, {"assembly", 11.0}, {"draw", 123.3}, {"d2", 0.0}, {"d55", 0.23}}; + d[key] = res; +} + +static void BM_taylor_map_upd(benchmark::State& state) { + for (auto _ : state) { + double res = calc_exp_taylor(); + updMapValue(res, "assembly"); + } +} + +void updValue(double res) { + static double d; static std::mutex mtx; { std::lock_guard lock(mtx); - d[key] = res; + d = res; } } static void BM_taylor_mutex_upd(benchmark::State& state) { for (auto _ : state) { double res = calc_exp_taylor(); - updValue(res, "assembly"); + updValue(res); } } @@ -119,6 +131,7 @@ BENCHMARK(BM_taylor_logger); BENCHMARK(BM_taylor_glog); BENCHMARK(BM_taylor_atomic_upd); BENCHMARK(BM_taylor_mutex_upd); +BENCHMARK(BM_taylor_map_upd); std::string caesar_encoder(const std::string& input) { static constexpr int small = 'a'; diff --git a/include/logger.hh b/include/logger.hh index d27c064..ac04bfb 100644 --- a/include/logger.hh +++ b/include/logger.hh @@ -22,10 +22,13 @@ class Logger { public: virtual ~Logger(); + + Logger(); explicit Logger(std::ostream& out); - Logger() = delete; Logger(Logger&) = delete; Logger(Logger&&) = delete; + Logger& operator=(Logger&) = delete; + Logger& operator=(Logger&&) = delete; /// @return success or not (already configured) bool configure(const std::vector& d); @@ -33,11 +36,11 @@ class Logger { template >> void add(const std::string& field, Metric metric) { - auto locked = active.load(); + auto locked = active.load(std::memory_order_acquire); // auto locked = active; auto it = locked->find(field); if (it == locked->end()) { - throw configErrorMsg; + throw configErrorMsg; // additional 30ns on bench ? } it->second = metric; } @@ -51,7 +54,8 @@ class Logger { std::unique_ptr worker; std::shared_ptr m1, m2; std::atomic> active; // impl may use mutex! - // std::shared_ptr active; + // std::shared_ptr active; // data race without atomic on swap + // operation }; } // namespace vptyp \ No newline at end of file diff --git a/src/logger.cc b/src/logger.cc index 301cc8c..b3c8ab4 100644 --- a/src/logger.cc +++ b/src/logger.cc @@ -1,4 +1,6 @@ #include "logger.hh" +#include +#include #include namespace vptyp { @@ -18,6 +20,11 @@ bool Logger::configure(const std::vector& d) { return true; } +Logger::Logger() + : m1(std::make_shared()), m2(std::make_shared()) { + worker = std::make_unique(*this, std::cout); +} + Logger::Logger(std::ostream& out) : m1(std::make_shared()), m2(std::make_shared()) { worker = std::make_unique(*this, out); @@ -31,7 +38,7 @@ class Logger::Worker { public: explicit Worker(Logger& father, std::ostream& out) : parent(father), out(out) { - thread = std::jthread([this] { routine(); }); + thread = std::thread([this] { routine(); }); } ~Worker() { @@ -54,14 +61,14 @@ class Logger::Worker { std::atomic state; Logger& parent; std::ostream& out; - std::jthread thread; + std::thread thread; // jthread not needed, as we anyway must wait for join }; void Logger::Worker::unroll() { if (!parent.isConfigured()) return; - auto tmp = parent.active.load(); + auto tmp = parent.active.load(std::memory_order_acquire); // auto tmp = parent.active; auto toBeActive = tmp == parent.m1 ? parent.m2 : parent.m1; while (!parent.active.compare_exchange_weak(tmp, toBeActive)) {