HIBF 1.0.0-rc.1
All Classes Namespaces Files Functions Variables Typedefs Friends Macros Modules Pages Concepts
timer.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2025, Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2025, Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#include <algorithm> // for max
13#include <atomic> // for atomic, __atomic_base, memory_order_relaxed
14#include <cassert> // for assert
15#include <chrono> // for duration, time_point, operator-, operator<=>, steady_clock
16#include <compare> // for operator>=, strong_ordering
17#include <concepts> // for same_as
18#include <cstdint> // for uint64_t
19
20#include <hibf/platform.hpp>
21
22namespace seqan::hibf
23{
24
25class concurrent_timer;
26
31{
32private:
34
35 steady_clock_t::time_point start_point{std::chrono::time_point<steady_clock_t>::max()};
36 steady_clock_t::time_point stop_point{};
37
38 steady_clock_t::rep ticks{};
39 steady_clock_t::rep max{};
40 uint64_t count{};
41
42 friend class concurrent_timer;
43
44public:
48 serial_timer() = default;
49 serial_timer(serial_timer const &) = default;
50 serial_timer & operator=(serial_timer const &) = default;
51 serial_timer(serial_timer &&) = default;
53 ~serial_timer() = default;
54
56
61 void start()
62 {
63 start_point = steady_clock_t::now();
64 }
65
70 void stop()
71 {
72 stop_point = steady_clock_t::now();
73 assert(stop_point >= start_point);
74 steady_clock_t::rep duration = (stop_point - start_point).count();
75
76 ticks += duration;
77 max = std::max(max, duration);
78 ++count;
79 }
80
82 template <typename timer_t>
84 void operator+=(timer_t const & other)
85 {
86 steady_clock_t::rep ticks_to_add{};
88 ticks_to_add = other.ticks.load();
89 else
90 ticks_to_add = other.ticks;
91
92 ticks += ticks_to_add;
93 max = std::max(max, ticks_to_add);
94 ++count;
95 }
97
102 double in_seconds() const
103 {
104 return std::chrono::duration<double>(steady_clock_t::duration{ticks}).count();
105 }
106
113 double max_in_seconds() const
114 {
115 return std::chrono::duration<double>(steady_clock_t::duration{max}).count();
116 }
117
127 double avg_in_seconds() const
128 {
129 assert(count > 0u);
130 return in_seconds() / count;
131 }
133
138 constexpr bool operator==(serial_timer const &) const
139 {
140 return true;
141 }
142
144 constexpr bool operator==(concurrent_timer const &) const
145 {
146 return true;
147 }
149};
150
155{
156private:
158
159 alignas(64) std::atomic<steady_clock_t::rep> ticks{};
160
161 steady_clock_t::time_point start_point{std::chrono::time_point<steady_clock_t>::max()};
162 steady_clock_t::time_point stop_point{};
163
164 alignas(64) std::atomic<steady_clock_t::rep> max{};
165 alignas(64) std::atomic<uint64_t> count{};
166
167 friend class serial_timer;
168
169 void update_max(steady_clock_t::rep const value)
170 {
171 for (steady_clock_t::rep previous_value = max;
172 previous_value < value && !max.compare_exchange_weak(previous_value, value, std::memory_order_relaxed);)
173 ;
174 }
175
176public:
181 concurrent_timer() = default;
184 ticks{other.ticks.load()},
185 start_point{other.start_point},
186 stop_point{other.stop_point},
187 max{other.max.load()},
188 count{other.count.load()}
189 {}
192 {
193 ticks = other.ticks.load();
194 start_point = other.start_point;
195 stop_point = other.stop_point;
196 max = other.max.load();
197 count = other.count.load();
198 return *this;
199 }
202 ticks{other.ticks.load()},
203 start_point{other.start_point},
204 stop_point{other.stop_point},
205 max{other.max.load()},
206 count{other.count.load()}
207 {}
210 {
211 ticks = other.ticks.load();
212 start_point = other.start_point;
213 stop_point = other.stop_point;
214 max = other.max.load();
215 count = other.count.load();
216 return *this;
217 }
219 ~concurrent_timer() = default;
221
226 void start()
227 {
228 start_point = steady_clock_t::now();
229 }
230
234 void stop()
235 {
236 stop_point = steady_clock_t::now();
237 assert(stop_point >= start_point);
238 steady_clock_t::rep duration = (stop_point - start_point).count();
239
240 ticks += duration;
241 update_max(duration);
242 ++count;
243 }
244
248 template <typename timer_t>
250 void operator+=(timer_t const & other)
251 {
252 ticks += other.ticks;
253 update_max(other.ticks);
254 ++count;
255 }
257
262 double in_seconds() const
263 {
264 return std::chrono::duration<double>(steady_clock_t::duration{ticks.load()}).count();
265 }
266
268 double max_in_seconds() const
269 {
270 return std::chrono::duration<double>(steady_clock_t::duration{max.load()}).count();
271 }
272
274 double avg_in_seconds() const
275 {
276 assert(count.load() > 0u);
277 return in_seconds() / count.load();
278 }
279
284 constexpr bool operator==(serial_timer const &) const
285 {
286 return true;
287 }
288
290 constexpr bool operator==(concurrent_timer const &) const
291 {
292 return true;
293 }
295};
296
297} // namespace seqan::hibf
A timer with a thread-safe operator+=().
Definition timer.hpp:155
void stop()
Stops the timer.
Definition timer.hpp:234
~concurrent_timer()=default
Defaulted.
double avg_in_seconds() const
Returns the average measured time interval in seconds.
Definition timer.hpp:274
constexpr bool operator==(serial_timer const &) const
Two timer are always equal.
Definition timer.hpp:284
constexpr bool operator==(concurrent_timer const &) const
Two timer are always equal.
Definition timer.hpp:290
concurrent_timer()=default
Defaulted.
double in_seconds() const
Returns the measured time in seconds.
Definition timer.hpp:262
concurrent_timer(concurrent_timer &&other) noexcept
Defaulted.
Definition timer.hpp:201
concurrent_timer & operator=(concurrent_timer &&other) noexcept
Defaulted.
Definition timer.hpp:209
concurrent_timer & operator=(concurrent_timer const &other)
Defaulted.
Definition timer.hpp:191
void start()
Starts the timer.
Definition timer.hpp:226
double max_in_seconds() const
Returns the maximum measured time interval in seconds.
Definition timer.hpp:268
concurrent_timer(concurrent_timer const &other)
Defaulted.
Definition timer.hpp:183
A timer.
Definition timer.hpp:31
constexpr bool operator==(serial_timer const &) const
Two timer are always equal.
Definition timer.hpp:138
serial_timer(serial_timer &&)=default
Defaulted.
double max_in_seconds() const
Returns the maximum measured time interval in seconds.
Definition timer.hpp:113
serial_timer()=default
Defaulted.
serial_timer & operator=(serial_timer &&)=default
Defaulted.
serial_timer & operator=(serial_timer const &)=default
Defaulted.
constexpr bool operator==(concurrent_timer const &) const
Two timer are always equal.
Definition timer.hpp:144
double avg_in_seconds() const
Returns the average measured time interval in seconds.
Definition timer.hpp:127
~serial_timer()=default
Defaulted.
void stop()
Stops the timer.
Definition timer.hpp:70
double in_seconds() const
Returns the measured time in seconds.
Definition timer.hpp:102
void start()
Starts the timer.
Definition timer.hpp:61
serial_timer(serial_timer const &)=default
Defaulted.
T compare_exchange_weak(T... args)
T is_base_of_v
T load(T... args)
Provides platform and dependency checks.