-
Notifications
You must be signed in to change notification settings - Fork 11
/
vs_tictoc.h
175 lines (145 loc) · 4.48 KB
/
vs_tictoc.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/**
* Copyright (c) 2016-2023 shuyuanmao <[email protected]>. All rights reserved.
* @author shuyuanmao <[email protected]>
* @date 2019-05-19 02:07
* @details evaluate the time cost.
*/
#pragma once
#include <chrono>
#include <deque>
#include <string>
namespace vs {
/** @brief Timer to use count time cost
* @code
* Timer t1;
* t1.start();
* // do something
* t1.stop();
* double cost = t1.getMsec(); // time cost in millisecond between start() and stop()
* @endcode
*/
class Timer {
public:
/** @brief constructor
* @note call start() inside when construct
*/
Timer() { start(); }
/** @brief set start time point */
void start() { t1 = std::chrono::system_clock::now(); }
/** @brief set stop time point */
double stop() {
t2 = std::chrono::system_clock::now();
return getMsec();
}
/** @brief get time cost in second from start() to stop() */
double getSec() const { return getMsec() * 1e-3; }
/** @brief get time cost in millisecond from start() to stop() */
double getMsec() const { return std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count() * kms; }
private:
std::chrono::system_clock::time_point t1, t2; ///< time point at start and stop
const static double kms; ///< convert count to millisecond
};
/** @brief first call tic, second call toc */
void tictoc(const char* name);
/** @brief start timer */
void tic(const char* name);
/** @brief return time between tic and toc [millisecond] */
double toc(const char* name);
/** @brief sleep milliseconds */
void msleep(double msec);
/** @brief get software ts, reset to 0 when application start. [second] */
double getSoftTs();
/** @brief a high-precision loop rate sleeper. if current loop execute time is less than loop time,
* it will sleep the rest of time.
* @code
* Rater loop_rate(100); //build a 100hz rater
* while (1) {
* //do something
* loop_rate.sleep(); // if the excecute time of above code is less than 10ms, this line will sleep to ensure that the
* // loop time is 10ms.
* }
* @endcode
*/
class Rater {
public:
/** @brief constructor
* @param[in] fps the loop rate [HZ]
* @param[in] precision sleep precision [ms]
*/
Rater(double fps, double precision = 1);
/** @brief sleep under max frame rate
* sleep to make sure time diff to last sleep not less than min time interval(=1/fps)
*/
void sleep();
double getFps() const { return m_fps; }
private:
Timer m_timer;
double m_fps; // frequency[HZ]
double m_loopms; // loop step[ms]
double m_precisionms; // rater precision[ms], the max sleep error.
};
/** @brief Calculate process FPS(Frames Per Second)
* @code
* FpsCalculator fc;
* for (int i = 0; i < 100; i++) {
* fc.start();
* // do process
* fc.stop();
* }
* double fps = fc.fps(); // get process FPS
* double costms = fc.costms(); // get average frame process cost in milliseconds
* @endcode
*/
class FpsCalculator {
public:
/** @brief constructor
* @param[in]queue_len: buffer length to store latest frame cost
*/
explicit FpsCalculator(int queue_len = 10);
/** @brief set start time-point */
void start();
/** @brief set stop time-point */
double stop();
/** @brief get process FPS */
double fps();
/** @brief get average frame process cost in milliseconds */
double costms();
/** @brief get max process cost in milliseconds */
double maxms();
private:
Timer m_timer; ///< timer to measure time cost
std::deque<double> m_queue; ///< buffer to store latest frame cost
int m_queue_len; ///< buffer length to store latest frame cost
};
class TsSleeper {
public:
/** @brief sleep to timestamp in seconds, first call will init ref timestamp and not sleep. */
void sleepTo(double ts) {
if (!init_) {
timer_.start();
init_ts_ = ts;
init_ = true;
return;
}
timer_.stop();
double sleep_ts = ts - init_ts_ - timer_.getSec();
if (sleep_ts > 0) vs::msleep(sleep_ts * 1e3);
}
private:
bool init_ = false; ///< whether init ts valid
double init_ts_ = 0; ///< init sleep to ts
vs::Timer timer_; ///< inner timer which starts in init
};
class TimeIt {
public:
TimeIt(const char* name = "") : name_(name) { timer_.start(); }
~TimeIt() {
timer_.stop();
printf("[%s]cost %.2f ms\n", name_.c_str(), timer_.getMsec());
}
private:
Timer timer_;
std::string name_;
};
#define VS_TIME_IT() vs::TimeIt vs_time_it(__func__)
} /* namespace vs */