From 941cc4cbc60aa3457dc540f812bb4f11d89db67d Mon Sep 17 00:00:00 2001 From: Enrico Seiler Date: Thu, 2 Nov 2023 15:32:32 +0100 Subject: [PATCH] [MISC] Add max and avg to timer --- include/hibf/misc/timer.hpp | 67 +++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/include/hibf/misc/timer.hpp b/include/hibf/misc/timer.hpp index 44d07c03..c9448b83 100644 --- a/include/hibf/misc/timer.hpp +++ b/include/hibf/misc/timer.hpp @@ -40,6 +40,10 @@ class timer using rep_t = std::conditional_t, std::chrono::steady_clock::rep>; + using count_t = std::conditional_t, uint64_t>; + + static constexpr int alignment = is_concurrent ? 64 : 8; + template friend class timer; @@ -58,7 +62,12 @@ class timer timer(timer const & other) requires is_concurrent - : start_{other.start_}, stop_{other.stop_}, ticks{other.ticks.load()} + : + start_{other.start_}, + stop_{other.stop_}, + ticks{other.ticks.load()}, + max{other.max.load()}, + count{other.count.load()} {} timer & operator=(timer const & other) requires is_concurrent @@ -66,6 +75,8 @@ class timer start_ = other.start_; stop_ = other.stop_; ticks = other.ticks.load(); + max = other.max.load(); + count = other.count.load(); return *this; } @@ -78,13 +89,18 @@ class timer { stop_ = std::chrono::steady_clock::now(); assert(stop_ >= start_); - ticks += (stop_ - start_).count(); + std::chrono::steady_clock::rep duration = (stop_ - start_).count(); + ticks += duration; + update_max(duration); + ++count; } template void operator+=(timer const & other) { ticks += other.ticks; + update_max(other.ticks); + ++count; } double in_seconds() const @@ -93,12 +109,38 @@ class timer return std::chrono::duration(std::chrono::steady_clock::duration{ticks.load()}).count(); } + double max_in_seconds() const + requires is_concurrent + { + return std::chrono::duration(std::chrono::steady_clock::duration{max.load()}).count(); + } + + double avg_in_seconds() const + requires is_concurrent + { + assert(count.load() > 0u); + return in_seconds() / count.load(); + } + // GCOVR_EXCL_START double in_seconds() const requires (!is_concurrent) { return std::chrono::duration(std::chrono::steady_clock::duration{ticks}).count(); } + + double max_in_seconds() const + requires (!is_concurrent) + { + return std::chrono::duration(std::chrono::steady_clock::duration{max}).count(); + } + + double avg_in_seconds() const + requires (!is_concurrent) + { + assert(count > 0u); + return in_seconds() / count; + } // GCOVR_EXCL_STOP // Timer are always equal. @@ -110,7 +152,26 @@ class timer private: std::chrono::steady_clock::time_point start_{std::chrono::time_point::max()}; std::chrono::steady_clock::time_point stop_{}; - rep_t ticks{}; + + alignas(alignment) rep_t ticks{}; + alignas(alignment) rep_t max{}; + alignas(alignment) count_t count{}; + + void update_max(std::chrono::steady_clock::rep const value) + requires is_concurrent + { + for (std::chrono::steady_clock::rep previous_value = max; + previous_value < value && !max.compare_exchange_weak(previous_value, value, std::memory_order_relaxed);) + ; + } + + // GCOVR_EXCL_START + void update_max(std::chrono::steady_clock::rep const value) + requires (!is_concurrent) + { + max = std::max(max, value); + } + // GCOVR_EXCL_STOP }; /*!\brief Alias for timer