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
235private:
238
240 DURATION& m_duration;
241};
242
243
252
253
258{
259public:
261 m_name( "Anonymous" ),
262 m_count( 0 )
263 {
264 }
265
266 PROF_COUNTER( const std::string& aName ) :
267 m_name( aName ),
268 m_count( 0 )
269 {
270 }
271
272 unsigned long long Count() const
273 {
274 return m_count.load();
275 }
276
277 void Reset()
278 {
279 m_count.store( 0 );
280 }
281
282 unsigned long long operator++( int )
283 {
284 return m_count++;
285 }
286
287 void Show( std::ostream& aStream = std::cerr )
288 {
289 if( m_name.size() )
290 aStream << m_name << ": ";
291
292 aStream << m_count.load();
293 aStream << std::endl;
294 }
295
296private:
297 std::string m_name;
298 std::atomic_ullong m_count;
299};
300
302{
303 public:
304 using CLOCK = std::chrono::high_resolution_clock;
305 using TIME_POINT = std::chrono::time_point<CLOCK>;
306
308 {
309 std::string name;
311 bool isTimer = false;
312 double timerDelta = 0;
313 };
314
315 LATENCY_PROBE( const std::string& aName, int aStages = 8 ) :
316 m_name( aName )
317 {
318 m_checkpoints.reserve( aStages );
319 }
320
321 void Reset()
322 {
323 m_start = CLOCK::now();
324 m_checkpoints.clear();
325 }
326
327 void Checkpoint( const std::string& aName )
328 {
329 CHECKPOINT chk;
330 chk.name = aName;
331 chk.timestamp = CLOCK::now();
332 m_checkpoints.push_back( chk );
333 }
334
335 void AddTimer( PROF_TIMER& aTimer )
336 {
337 CHECKPOINT chk;
338 chk.name = aTimer.GetName();
339 chk.isTimer = true;
340 chk.timerDelta = aTimer.msecs();
341 m_checkpoints.push_back( chk );
342 }
343
344 std::string to_string();
345
347 {
348 using DUR_MS = std::chrono::duration<double, std::milli>;
349 return static_cast<DUR_MS>( a - b ).count();
350 }
351
352 private:
353
355 std::string m_name;
356 std::vector<CHECKPOINT> m_checkpoints;
357};
358
359#endif // TPROFILE_H
std::string to_string()
Definition profile.cpp:75
void AddTimer(PROF_TIMER &aTimer)
Definition profile.h:335
TIME_POINT m_start
Definition profile.h:354
void Checkpoint(const std::string &aName)
Definition profile.h:327
std::chrono::high_resolution_clock CLOCK
Definition profile.h:304
std::vector< CHECKPOINT > m_checkpoints
Definition profile.h:356
double delta_ms(TIME_POINT a, TIME_POINT b)
Definition profile.h:346
void Reset()
Definition profile.h:321
std::chrono::time_point< CLOCK > TIME_POINT
Definition profile.h:305
std::string m_name
Definition profile.h:355
LATENCY_PROBE(const std::string &aName, int aStages=8)
Definition profile.h:315
unsigned long long operator++(int)
Definition profile.h:282
PROF_COUNTER(const std::string &aName)
Definition profile.h:266
unsigned long long Count() const
Definition profile.h:272
void Show(std::ostream &aStream=std::cerr)
Definition profile.h:287
std::atomic_ullong m_count
Definition profile.h:298
void Reset()
Definition profile.h:277
std::string m_name
Definition profile.h:297
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
DURATION & m_duration
The duration to update at the end of the scope.
Definition profile.h:240
SCOPED_PROF_TIMER(DURATION &aDuration)
Definition profile.h:225
PROF_TIMER m_counter
The counter to use to do the profiling.
Definition profile.h:237
int64_t GetRunningMicroSecs()
An alternate way to calculate an elapsed time (in microsecondes) to class PROF_COUNTER.