1 | /******************************************************************************* |
2 | * Copyright 2021-2022 Intel Corporation |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | *******************************************************************************/ |
16 | |
17 | #ifndef UTILS_TIMER_HPP |
18 | #define UTILS_TIMER_HPP |
19 | |
20 | #include <map> |
21 | #include <string> |
22 | |
23 | #define TIME_FUNC(func, res, name) \ |
24 | do { \ |
25 | auto &t = res->timer_map.get_timer(name); \ |
26 | t.start(); \ |
27 | func; \ |
28 | t.stamp(); \ |
29 | } while (0) |
30 | |
31 | // Designated timer to calculate time spent on reference computations |
32 | #define TIME_REF(func) TIME_FUNC(func, res, timer::timer_t::ref_timer) |
33 | |
34 | namespace timer { |
35 | |
36 | struct timer_t { |
37 | enum mode_t { min = 0, avg = 1, max = 2, sum = 3, n_modes }; |
38 | |
39 | timer_t() { reset(); } |
40 | |
41 | // Fully reset the measurements |
42 | void reset(); |
43 | // Restart timer |
44 | void start(); |
45 | // Stop timer & update statistics |
46 | void stop(int add_times, int64_t add_ticks, double add_ms); |
47 | |
48 | void stamp(int add_times = 1); |
49 | |
50 | void stamp_with_frequency(int add_times, double add_ms, double freq) { |
51 | uint64_t add_ticks = (uint64_t)(add_ms * freq / 1e3); |
52 | stop(add_times, add_ticks, add_ms); |
53 | } |
54 | |
55 | int times() const { return times_; } |
56 | |
57 | double total_ms() const { return ms_[avg]; } |
58 | |
59 | double ms(mode_t mode = min) const { |
60 | if (!times()) return 0; // nothing to report |
61 | return ms_[mode] / (mode == avg ? times() : 1); |
62 | } |
63 | |
64 | double sec(mode_t mode = min) const { return ms(mode) / 1e3; } |
65 | |
66 | uint64_t ticks(mode_t mode = min) const { |
67 | if (!times()) return 0; // nothing to report |
68 | return ticks_[mode] / (mode == avg ? times() : 1); |
69 | } |
70 | |
71 | timer_t &operator=(const timer_t &rhs); |
72 | |
73 | int times_; |
74 | uint64_t ticks_[n_modes], ticks_start_; |
75 | double ms_[n_modes], ms_start_; |
76 | |
77 | // Section with timer fixed timer names for ease of use |
78 | static const std::string perf_timer; |
79 | static const std::string ref_timer; |
80 | }; |
81 | |
82 | struct timer_map_t { |
83 | timer_t &get_timer(const std::string &name); |
84 | |
85 | timer_t &perf_timer(); |
86 | |
87 | std::map<std::string, timer_t> timers; |
88 | }; |
89 | |
90 | } // namespace timer |
91 | |
92 | #endif |
93 | |