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
104 void Show( std::ostream& aStream = std::cerr )
105 {
106 using DURATION = std::chrono::duration<double, std::nano>;
107
108 const auto duration = SinceStart<DURATION>();
109 const double cnt = duration.count();
110
111 if( m_name.size() )
112 {
113 aStream << m_name << " took ";
114 }
115
116 if( cnt < 1e3 )
117 aStream << cnt << "ns";
118 else if( cnt < 1e6 )
119 aStream << ( cnt / 1e3 ) << "µs";
120 else if( cnt < 1e9 )
121 aStream << ( cnt / 1e6 ) << "ms";
122 else
123 aStream << ( cnt / 1e9 ) << "s";
124
125 aStream << std::endl;
126 }
127
133 template <typename DURATION>
134 DURATION SinceStart( bool aSinceLast = false )
135 {
136 const TIME_POINT stoptime = m_running ? CLOCK::now() : m_stoptime;
137 const TIME_POINT starttime = aSinceLast ? m_lasttime : m_starttime;
138
139 m_lasttime = stoptime;
140
141 return std::chrono::duration_cast<DURATION>( stoptime - starttime );
142 }
143
148 double msecs( bool aSinceLast = false )
149 {
150 using DUR_MS = std::chrono::duration<double, std::milli>;
151 return SinceStart<DUR_MS>( aSinceLast ).count();
152 }
153
154 std::string to_string()
155 {
156 using DURATION = std::chrono::duration<double, std::nano>;
157
158 const auto duration = SinceStart<DURATION>();
159 const double cnt = duration.count();
160 std::string retv;
161
162 if( !m_name.empty() )
163 retv = m_name + ": ";
164
165 if( !m_started )
166 {
167 retv += "none";
168 return retv;
169 }
170
171 std::stringstream time;
172
173 if( cnt < 1e3 )
174 time << cnt << "ns";
175 else if( cnt < 1e6 )
176 time << ( cnt / 1e3 ) << "µs";
177 else if( cnt < 1e9 )
178 time << ( cnt / 1e6 ) << "ms";
179 else
180 time << ( cnt / 1e9 ) << "s";
181
182 retv += time.str();
183
184 return retv;
185 }
186
187 const std::string& GetName() const { return m_name; }
188
189private:
190 std::string m_name; // a string printed in message
193
194 using CLOCK = std::chrono::high_resolution_clock;
195 using TIME_POINT = std::chrono::time_point<CLOCK>;
196
198};
199
200
221template <typename DURATION>
223{
224public:
225 SCOPED_PROF_TIMER( DURATION& aDuration ) : PROF_TIMER(), m_duration( aDuration )
226 {
227 }
228
230 {
231 // update the output
232 m_duration = m_counter.SinceStart<DURATION>();
233 }
234
235 // No copying or it can lead to double or early updating of the duration.
238
239private:
242
244 DURATION& m_duration;
245};
246
247
256
257
262{
263public:
265 m_name( "Anonymous" ),
266 m_count( 0 )
267 {
268 }
269
270 PROF_COUNTER( const std::string& aName ) :
271 m_name( aName ),
272 m_count( 0 )
273 {
274 }
275
276 unsigned long long Count() const
277 {
278 return m_count.load();
279 }
280
281 void Reset()
282 {
283 m_count.store( 0 );
284 }
285
286 unsigned long long operator++( int )
287 {
288 return m_count++;
289 }
290
291 void Show( std::ostream& aStream = std::cerr )
292 {
293 if( m_name.size() )
294 aStream << m_name << ": ";
295
296 aStream << m_count.load();
297 aStream << std::endl;
298 }
299
300private:
301 std::string m_name;
302 std::atomic_ullong m_count;
303};
304
306{
307 public:
308 using CLOCK = std::chrono::high_resolution_clock;
309 using TIME_POINT = std::chrono::time_point<CLOCK>;
310
312 {
313 std::string name;
315 bool isTimer = false;
316 double timerDelta = 0;
317 };
318
319 LATENCY_PROBE( const std::string& aName, int aStages = 8 ) :
320 m_name( aName )
321 {
322 m_checkpoints.reserve( aStages );
323 }
324
325 void Reset()
326 {
327 m_start = CLOCK::now();
328 m_checkpoints.clear();
329 }
330
331 void Checkpoint( const std::string& aName )
332 {
333 CHECKPOINT chk;
334 chk.name = aName;
335 chk.timestamp = CLOCK::now();
336 m_checkpoints.push_back( chk );
337 }
338
339 void AddTimer( PROF_TIMER& aTimer )
340 {
341 CHECKPOINT chk;
342 chk.name = aTimer.GetName();
343 chk.isTimer = true;
344 chk.timerDelta = aTimer.msecs();
345 m_checkpoints.push_back( chk );
346 }
347
348 std::string to_string();
349
351 {
352 using DUR_MS = std::chrono::duration<double, std::milli>;
353 return static_cast<DUR_MS>( a - b ).count();
354 }
355
356 private:
357
359 std::string m_name;
360 std::vector<CHECKPOINT> m_checkpoints;
361};
362
363#endif // TPROFILE_H
std::string to_string()
Definition profile.cpp:75
void AddTimer(PROF_TIMER &aTimer)
Definition profile.h:339
TIME_POINT m_start
Definition profile.h:358
void Checkpoint(const std::string &aName)
Definition profile.h:331
std::chrono::high_resolution_clock CLOCK
Definition profile.h:308
std::vector< CHECKPOINT > m_checkpoints
Definition profile.h:360
double delta_ms(TIME_POINT a, TIME_POINT b)
Definition profile.h:350
void Reset()
Definition profile.h:325
std::chrono::time_point< CLOCK > TIME_POINT
Definition profile.h:309
std::string m_name
Definition profile.h:359
LATENCY_PROBE(const std::string &aName, int aStages=8)
Definition profile.h:319
unsigned long long operator++(int)
Definition profile.h:286
PROF_COUNTER(const std::string &aName)
Definition profile.h:270
unsigned long long Count() const
Definition profile.h:276
void Show(std::ostream &aStream=std::cerr)
Definition profile.h:291
std::atomic_ullong m_count
Definition profile.h:302
void Reset()
Definition profile.h:281
std::string m_name
Definition profile.h:301
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:104
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:194
const std::string & GetName() const
Definition profile.h:187
DURATION SinceStart(bool aSinceLast=false)
Definition profile.h:134
void Start()
Start or restart the counter.
Definition profile.h:74
TIME_POINT m_lasttime
Definition profile.h:197
std::string to_string()
Definition profile.h:154
bool m_started
Definition profile.h:192
TIME_POINT m_stoptime
Definition profile.h:197
bool m_running
Definition profile.h:191
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:195
TIME_POINT m_starttime
Definition profile.h:197
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:190
double msecs(bool aSinceLast=false)
Definition profile.h:148
SCOPED_PROF_TIMER(const SCOPED_PROF_TIMER &)=delete
DURATION & m_duration
The duration to update at the end of the scope.
Definition profile.h:244
SCOPED_PROF_TIMER & operator=(const SCOPED_PROF_TIMER &)=delete
SCOPED_PROF_TIMER(DURATION &aDuration)
Definition profile.h:225
PROF_TIMER m_counter
The counter to use to do the profiling.
Definition profile.h:241
int64_t GetRunningMicroSecs()
An alternate way to calculate an elapsed time (in microsecondes) to class PROF_COUNTER.