KiCad PCB EDA Suite
Loading...
Searching...
No Matches
profile.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2013 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Tomasz Wlostowski <[email protected]>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
26
27#ifndef TPROFILE_H
28#define TPROFILE_H
29
30#include <atomic>
31#include <chrono>
32#include <sstream>
33#include <string>
34#include <iostream>
35#include <iomanip>
36#include <cstdint>
37#include <vector>
38
46{
47public:
54 PROF_TIMER( const std::string& aName, bool aAutostart = true ) :
55 m_name( aName ), m_running( false )
56 {
57 if( aAutostart )
58 Start();
59 }
60
67 {
68 Start();
69 }
70
74 void Start()
75 {
76 m_started = true;
77 m_running = true;
78 m_starttime = CLOCK::now();
80 }
81
82
86 void Stop()
87 {
88 if( !m_running )
89 return;
90
91 m_stoptime = CLOCK::now();
92 m_running = false;
93 }
94
103 void Show( std::ostream& aStream = std::cerr )
104 {
105 using DURATION = std::chrono::duration<double, std::nano>;
106
107 const auto duration = SinceStart<DURATION>();
108 const double cnt = duration.count();
109
110 if( m_name.size() )
111 {
112 aStream << m_name << " took ";
113 }
114
115 if( cnt < 1e3 )
116 aStream << cnt << "ns";
117 else if( cnt < 1e6 )
118 aStream << ( cnt / 1e3 ) << "µs";
119 else if( cnt < 1e9 )
120 aStream << ( cnt / 1e6 ) << "ms";
121 else
122 aStream << ( cnt / 1e9 ) << "s";
123
124 aStream << std::endl;
125 }
126
132 template <typename DURATION>
133 DURATION SinceStart( bool aSinceLast = false )
134 {
135 const TIME_POINT stoptime = m_running ? CLOCK::now() : m_stoptime;
136 const TIME_POINT starttime = aSinceLast ? m_lasttime : m_starttime;
137
138 m_lasttime = stoptime;
139
140 return std::chrono::duration_cast<DURATION>( stoptime - starttime );
141 }
142
147 double msecs( bool aSinceLast = false )
148 {
149 using DUR_MS = std::chrono::duration<double, std::milli>;
150 return SinceStart<DUR_MS>( aSinceLast ).count();
151 }
152
153 std::string to_string()
154 {
155 using DURATION = std::chrono::duration<double, std::nano>;
156
157 const auto duration = SinceStart<DURATION>();
158 const double cnt = duration.count();
159 std::string retv;
160
161 if( !m_name.empty() )
162 retv = m_name + ": ";
163
164 if( !m_started )
165 {
166 retv += "none";
167 return retv;
168 }
169
170 std::stringstream time;
171
172 if( cnt < 1e3 )
173 time << cnt << "ns";
174 else if( cnt < 1e6 )
175 time << ( cnt / 1e3 ) << "µs";
176 else if( cnt < 1e9 )
177 time << ( cnt / 1e6 ) << "ms";
178 else
179 time << ( cnt / 1e9 ) << "s";
180
181 retv += time.str();
182
183 return retv;
184 }
185
186 const std::string& GetName() const { return m_name; }
187
188private:
189 std::string m_name; // a string printed in message
192
193 using CLOCK = std::chrono::high_resolution_clock;
194 using TIME_POINT = std::chrono::time_point<CLOCK>;
195
197};
198
199
218template <typename DURATION>
220{
221public:
222 SCOPED_PROF_TIMER( DURATION& aDuration ) : PROF_TIMER(), m_duration( aDuration )
223 {
224 }
225
227 {
228 // update the output
229 m_duration = m_counter.SinceStart<DURATION>();
230 }
231
232private:
235
237 DURATION& m_duration;
238};
239
240
249
250
255{
256public:
258 m_name( "Anonymous" ),
259 m_count( 0 )
260 {
261 }
262
263 PROF_COUNTER( const std::string& aName ) :
264 m_name( aName ),
265 m_count( 0 )
266 {
267 }
268
269 unsigned long long Count() const
270 {
271 return m_count.load();
272 }
273
274 void Reset()
275 {
276 m_count.store( 0 );
277 }
278
279 unsigned long long operator++( int )
280 {
281 return m_count++;
282 }
283
284 void Show( std::ostream& aStream = std::cerr )
285 {
286 if( m_name.size() )
287 aStream << m_name << ": ";
288
289 aStream << m_count.load();
290 aStream << std::endl;
291 }
292
293private:
294 std::string m_name;
295 std::atomic_ullong m_count;
296};
297
299{
300 public:
301 using CLOCK = std::chrono::high_resolution_clock;
302 using TIME_POINT = std::chrono::time_point<CLOCK>;
303
305 {
306 std::string name;
308 bool isTimer = false;
309 double timerDelta = 0;
310 };
311
312 LATENCY_PROBE( const std::string& aName, int aStages = 8 ) :
313 m_name( aName )
314 {
315 m_checkpoints.reserve( aStages );
316 }
317
318 void Reset()
319 {
320 m_start = CLOCK::now();
321 m_checkpoints.clear();
322 }
323
324 void Checkpoint( const std::string& aName )
325 {
326 CHECKPOINT chk;
327 chk.name = aName;
328 chk.timestamp = CLOCK::now();
329 m_checkpoints.push_back( chk );
330 }
331
332 void AddTimer( PROF_TIMER& aTimer )
333 {
334 CHECKPOINT chk;
335 chk.name = aTimer.GetName();
336 chk.isTimer = true;
337 chk.timerDelta = aTimer.msecs();
338 m_checkpoints.push_back( chk );
339 }
340
341 std::string to_string();
342
344 {
345 using DUR_MS = std::chrono::duration<double, std::milli>;
346 return static_cast<DUR_MS>( a - b ).count();
347 }
348
349 private:
350
352 std::string m_name;
353 std::vector<CHECKPOINT> m_checkpoints;
354};
355
356#endif // TPROFILE_H
std::string to_string()
Definition profile.cpp:75
void AddTimer(PROF_TIMER &aTimer)
Definition profile.h:332
TIME_POINT m_start
Definition profile.h:351
void Checkpoint(const std::string &aName)
Definition profile.h:324
std::chrono::high_resolution_clock CLOCK
Definition profile.h:301
std::vector< CHECKPOINT > m_checkpoints
Definition profile.h:353
double delta_ms(TIME_POINT a, TIME_POINT b)
Definition profile.h:343
void Reset()
Definition profile.h:318
std::chrono::time_point< CLOCK > TIME_POINT
Definition profile.h:302
std::string m_name
Definition profile.h:352
LATENCY_PROBE(const std::string &aName, int aStages=8)
Definition profile.h:312
unsigned long long operator++(int)
Definition profile.h:279
PROF_COUNTER(const std::string &aName)
Definition profile.h:263
unsigned long long Count() const
Definition profile.h:269
void Show(std::ostream &aStream=std::cerr)
Definition profile.h:284
std::atomic_ullong m_count
Definition profile.h:295
void Reset()
Definition profile.h:274
std::string m_name
Definition profile.h:294
A small class to help profiling.
Definition profile.h:46
void Show(std::ostream &aStream=std::cerr)
Print the elapsed time (in a suitable unit) to a stream.
Definition profile.h:103
void Stop()
Save the time when this function was called, and set the counter stane to stop.
Definition profile.h:86
std::chrono::high_resolution_clock CLOCK
Definition profile.h:193
const std::string & GetName() const
Definition profile.h:186
DURATION SinceStart(bool aSinceLast=false)
Definition profile.h:133
void Start()
Start or restart the counter.
Definition profile.h:74
TIME_POINT m_lasttime
Definition profile.h:196
std::string to_string()
Definition profile.h:153
bool m_started
Definition profile.h:191
TIME_POINT m_stoptime
Definition profile.h:196
bool m_running
Definition profile.h:190
PROF_TIMER()
Create a PROF_COUNTER for measuring an elapsed time in milliseconds.
Definition profile.h:66
std::chrono::time_point< CLOCK > TIME_POINT
Definition profile.h:194
TIME_POINT m_starttime
Definition profile.h:196
PROF_TIMER(const std::string &aName, bool aAutostart=true)
Create a PROF_COUNTER for measuring an elapsed time in milliseconds.
Definition profile.h:54
std::string m_name
Definition profile.h:189
double msecs(bool aSinceLast=false)
Definition profile.h:147
DURATION & m_duration
Definition profile.h:237
SCOPED_PROF_TIMER(DURATION &aDuration)
Definition profile.h:222
PROF_TIMER m_counter
< The counter to use to do the profiling
Definition profile.h:234
int64_t GetRunningMicroSecs()
An alternate way to calculate an elapsed time (in microsecondes) to class PROF_COUNTER.