Robot Simulator of the Robotics Group for Self-Organization of Control  0.8.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
quickprof.h
Go to the documentation of this file.
1 /************************************************************************
2 * QuickProf *
3 * http://quickprof.sourceforge.net *
4 * Copyright (C) 2006-2008 *
5 * Tyler Streeter (http://www.tylerstreeter.net) *
6 * *
7 * This library is free software; you can redistribute it and/or *
8 * modify it under the terms of EITHER: *
9 * (1) The GNU Lesser General Public License as published by the Free *
10 * Software Foundation; either version 2.1 of the License, or (at *
11 * your option) any later version. The text of the GNU Lesser *
12 * General Public License is included with this library in the *
13 * file license-LGPL.txt. *
14 * (2) The BSD-style license that is included with this library in *
15 * the file license-BSD.txt. *
16 * (3) The zlib/libpng license that is included with this library in *
17 * the file license-zlib-libpng.txt. *
18 * *
19 * This library is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
22 * license-LGPL.txt, license-BSD.txt, and license-zlib-libpng.txt for *
23 * more details. *
24 ************************************************************************/
25 
26 // Please visit the project website (http://quickprof.sourceforge.net)
27 // for usage instructions.
28 
29 #ifndef QUICK_PROF_H
30 #define QUICK_PROF_H
31 
32 #include <iostream>
33 #include <fstream>
34 #include <sstream>
35 #include <map>
36 #include <cmath>
37 
38 #if defined(WIN32) || defined(_WIN32)
39  #define USE_WINDOWS_TIMERS
40  #include <windows.h>
41  #include <time.h>
42 #else
43  #include <sys/time.h>
44 #endif
45 
46 /// Use this macro to access the profiler singleton. For example:
47 /// PROFILER.init();
48 /// ...
49 /// PROFILER.beginBlock("foo");
50 /// foo();
51 /// PROFILER.endBlock("foo");
52 #define PROFILER quickprof::Profiler::instance()
53 
54 /// The main namespace that contains everything.
55 namespace quickprof
56 {
57  /// A simple data structure representing a single timed block
58  /// of code.
59  struct ProfileBlock
60  {
62  {
67  }
68 
69  /// The starting time (in us) of the current block update.
70  unsigned long long int currentBlockStartMicroseconds;
71 
72  /// The accumulated time (in us) spent in this block during the
73  /// current profiling cycle.
74  unsigned long long int currentCycleTotalMicroseconds;
75 
76  /// The accumulated time (in us) spent in this block during the
77  /// past profiling cycle.
79 
80  /// The total accumulated time (in us) spent in this block.
81  unsigned long long int totalMicroseconds;
82  };
83 
84  /// A cross-platform clock class inspired by the Timer classes in
85  /// Ogre (http://www.ogre3d.org).
86  class Clock
87  {
88  public:
90  {
91 #ifdef USE_WINDOWS_TIMERS
92  QueryPerformanceFrequency(&mClockFrequency);
93 #endif
94  reset();
95  }
96 
98  {
99  }
100 
101  /**
102  Resets the initial reference time.
103  */
104  void reset()
105  {
106 #ifdef USE_WINDOWS_TIMERS
107  QueryPerformanceCounter(&mStartTime);
108  mStartTick = GetTickCount();
109  mPrevClockCycles = 0;
110 #else
111  gettimeofday(&mStartTime, NULL);
112 #endif
113  }
114 
115  /**
116  Returns the time in us since the last call to reset or since
117  the Clock was created.
118 
119  @return The requested time in microseconds. Assuming 64-bit
120  integers are available, the return value is valid for 2^63
121  clock cycles (over 104 years w/ clock frequency 2.8 GHz).
122  */
123  unsigned long long int getTimeMicroseconds()
124  {
125 #ifdef USE_WINDOWS_TIMERS
126  // Compute the number of elapsed clock cycles since the
127  // clock was created/reset. Using 64-bit signed ints, this
128  // is valid for 2^63 clock cycles (over 104 years w/ clock
129  // frequency 2.8 GHz).
130  LARGE_INTEGER currentTime;
131  QueryPerformanceCounter(&currentTime);
132  LONGLONG clockCycles = currentTime.QuadPart -
133  mStartTime.QuadPart;
134 
135  // Compute the total elapsed seconds. This is valid for 2^63
136  // clock cycles (over 104 years w/ clock frequency 2.8 GHz).
137  LONGLONG sec = clockCycles / mClockFrequency.QuadPart;
138 
139  // Check for unexpected leaps in the Win32 performance counter.
140  // (This is caused by unexpected data across the PCI to ISA
141  // bridge, aka south bridge. See Microsoft KB274323.) Avoid
142  // the problem with GetTickCount() wrapping to zero after 47
143  // days (because it uses 32-bit unsigned ints to represent
144  // milliseconds).
145  LONGLONG msec1 = sec * 1000 + (clockCycles - sec *
146  mClockFrequency.QuadPart) * 1000 / mClockFrequency.QuadPart;
147  DWORD tickCount = GetTickCount();
148  if (tickCount < mStartTick)
149  {
150  mStartTick = tickCount;
151  }
152  LONGLONG msec2 = (LONGLONG)(tickCount - mStartTick);
153  LONGLONG msecDiff = msec1 - msec2;
154  if (msecDiff < -100 || msecDiff > 100)
155  {
156  // Adjust the starting time forwards.
157  LONGLONG adjustment = (std::min)(msecDiff *
158  mClockFrequency.QuadPart / 1000, clockCycles -
159  mPrevClockCycles);
160  mStartTime.QuadPart += adjustment;
161  clockCycles -= adjustment;
162 
163  // Update the measured seconds with the adjustments.
164  sec = clockCycles / mClockFrequency.QuadPart;
165  }
166 
167  // Compute the milliseconds part. This is always valid since
168  // it will never be greater than 1000000.
169  LONGLONG usec = (clockCycles - sec * mClockFrequency.QuadPart) *
170  1000000 / mClockFrequency.QuadPart;
171 
172  // Store the current elapsed clock cycles for adjustments next
173  // time.
174  mPrevClockCycles = clockCycles;
175 
176  // The return value here is valid for 2^63 clock cycles (over
177  // 104 years w/ clock frequency 2.8 GHz).
178  return sec * 1000000 + usec;
179 #else
180  // Assuming signed 32-bit integers for tv_sec and tv_usec, and
181  // casting the seconds difference to a 64-bit unsigned long long
182  // int, the return value here is valid for over 136 years.
183  struct timeval currentTime;
184  gettimeofday(&currentTime, NULL);
185  return (unsigned long long int)(currentTime.tv_sec -
186  mStartTime.tv_sec) * 1000000 + (currentTime.tv_usec -
187  mStartTime.tv_usec);
188 #endif
189  }
190 
191  private:
192 #ifdef USE_WINDOWS_TIMERS
193  LARGE_INTEGER mClockFrequency;
194  DWORD mStartTick;
195  LONGLONG mPrevClockCycles;
196  LARGE_INTEGER mStartTime;
197 #else
198  struct timeval mStartTime;
199 #endif
200  };
201 
202  /// A set of ways to represent timing results.
204  {
209  };
210 
211  /// A singleton class that manages timing for a set of profiling blocks.
212  class Profiler
213  {
214  public:
215  /**
216  Useful for creating multiple Profiler instances.
217 
218  Normally the Profiler class should be accessed only through the
219  singleton instance method, which provides global access to a single
220  static Profiler instance. However, it is also possible to create
221  several local Profiler instances, if necessary.
222  */
223  inline Profiler();
224 
225  inline ~Profiler();
226 
227  /**
228  Accesses the singleton instance.
229 
230  @return The Profiler instance.
231  */
232  inline static Profiler& instance();
233 
234  /**
235  Initializes the profiler.
236 
237  This must be called first. If this is never called, the profiler
238  is effectively disabled, and all other functions will return
239  immediately. This can be called more than once to re-initialize the
240  profiler, which erases all previous profiling block names and their
241  timing data.
242 
243  @param smoothing The measured duration for each profile
244  block can be averaged across multiple
245  cycles, and this parameter defines the
246  smoothness of this averaging process.
247  The higher the value, the smoother the
248  resulting average durations will appear.
249  Leaving it at zero will essentially
250  disable the smoothing effect. More
251  specifically, this parameter is a time
252  constant (defined in terms of cycles) that
253  defines an exponentially-weighted moving
254  average. For example, a value of 4.0
255  means the past four cycles will contribute
256  63% of the current weighted average. This
257  value must be >= 0.
258  @param outputFilename If defined, enables timing data to be
259  printed to a data file for later analysis.
260  @param printPeriod Defines how often data is printed to the
261  file, in number of profiling cycles. For
262  example, set this to 1 if you want data
263  printed after each cycle, or 5 if you want
264  it printed every 5 cycles. It is a good
265  idea to increase this if you don't want
266  huge data files. Keep in mind, however,
267  that when you increase this, you might
268  want to increase the smoothing
269  parameter. (A good heuristic is to set
270  the smoothing parameter equal to the
271  print period.) This value must be >= 1.
272  @param printFormat Defines the format used when printing data
273  to a file.
274  */
275  inline void init(double smoothing=0.0,
276  const std::string& outputFilename="", size_t printPeriod=1,
277  TimeFormat printFormat=MILLISECONDS);
278 
279  /**
280  Begins timing the named block of code.
281 
282  @param name The name of the block.
283  */
284  inline void beginBlock(const std::string& name);
285 
286  /**
287  Defines the end of the named timing block.
288 
289  @param name The name of the block.
290  */
291  inline void endBlock(const std::string& name);
292 
293  /**
294  Defines the end of a profiling cycle.
295 
296  Use this regularly by calling it at the end of all timing blocks.
297  This is necessary for smoothing and for file output, but not if
298  you just want a total summary at the end of execution (i.e. from
299  getSummary). This must not be called within a timing block.
300  */
301  inline void endCycle();
302 
303  /**
304  Returns the average time used in the named block per profiling cycle.
305 
306  If smoothing is disabled (see init), this returns the most recent
307  duration measurement.
308 
309  @param name The name of the block.
310  @param format The desired time format to use for the result.
311  @return The block's average duration per cycle.
312  */
313  inline double getAvgDuration(const std::string& name,
314  TimeFormat format)const;
315 
316  /**
317  Returns the total time spent in the named block since the profiler was
318  initialized.
319 
320  @param name The name of the block.
321  @param format The desired time format to use for the result.
322  @return The block total time.
323  */
324  inline double getTotalDuration(const std::string& name,
325  TimeFormat format);
326 
327  /**
328  Computes the elapsed time since the profiler was initialized.
329 
330  @param format The desired time format to use for the result.
331  @return The elapsed time.
332  */
333  inline double getTimeSinceInit(TimeFormat format);
334 
335  /**
336  Returns a summary of total times in each block.
337 
338  @param format The desired time format to use for the results.
339  @return The timing summary as a string.
340  */
341  inline std::string getSummary(TimeFormat format=PERCENT);
342 
343  private:
344  /**
345  Returns everything to its initial state.
346 
347  Deallocates memory, closes output files, and resets all variables.
348  This is called when the profiler is re-initialized and when the
349  process exits.
350  */
351  inline void destroy();
352 
353  /**
354  Prints an error message to standard output.
355 
356  @param msg The string to print.
357  */
358  inline void printError(const std::string& msg)const;
359 
360  /**
361  Returns a named profile block.
362 
363  @param name The name of the block to return.
364  @return The named ProfileBlock, or NULL if it can't be found.
365  */
366  inline ProfileBlock* getProfileBlock(const std::string& name)const;
367 
368  /**
369  Returns the appropriate suffix string for the given time format.
370 
371  @return The suffix string.
372  */
373  inline std::string getSuffixString(TimeFormat format)const;
374 
375  /// Determines whether the profiler is enabled.
376  bool mEnabled;
377 
378  /// The clock used to time profile blocks.
379  Clock mClock;
380 
381  /// The starting time (in us) of the current profiling cycle.
382  unsigned long long int mCurrentCycleStartMicroseconds;
383 
384  /// The average profiling cycle duration (in us). If smoothing is
385  /// disabled, this is the same as the duration of the most recent
386  /// cycle.
387  double mAvgCycleDurationMicroseconds;
388 
389  /// Internal map of named profile blocks.
390  std::map<std::string, ProfileBlock*> mProfileBlocks;
391 
392  /// The data output file used if this feature is enabled in init.
393  std::ofstream mOutputFile;
394 
395  /// Tracks whether we have begun printing data to the output file.
396  bool mFirstFileOutput;
397 
398  /// A pre-computed scalar used to update exponentially-weighted moving
399  /// averages.
400  double mMovingAvgScalar;
401 
402  /// Determines how often (in number of profiling cycles) timing data
403  /// is printed to the output file.
404  size_t mPrintPeriod;
405 
406  /// The time format used when printing timing data to the output file.
407  TimeFormat mPrintFormat;
408 
409  /// Keeps track of how many cycles have elapsed (for printing).
410  size_t mCycleCounter;
411 
412  /// Used to update the initial average cycle times.
413  bool mFirstCycle;
414  };
415 
417  {
418  mEnabled = false;
419  mCurrentCycleStartMicroseconds = 0;
420  mAvgCycleDurationMicroseconds = 0;
421  mFirstFileOutput = true;
422  mMovingAvgScalar = 0;
423  mPrintPeriod = 1;
424  mPrintFormat = SECONDS;
425  mCycleCounter = 0;
426  mFirstCycle = true;
427  }
428 
430  {
431  // This is called when the program exits because the singleton
432  // instance is static.
433 
434  destroy();
435  }
436 
438  {
439  static Profiler self;
440  return self;
441  }
442 
443  void Profiler::destroy()
444  {
445  mEnabled = false;
446  mClock.reset();
447  mCurrentCycleStartMicroseconds = 0;
448  mAvgCycleDurationMicroseconds = 0;
449  while (!mProfileBlocks.empty())
450  {
451  delete (*mProfileBlocks.begin()).second;
452  mProfileBlocks.erase(mProfileBlocks.begin());
453  }
454  if (mOutputFile.is_open())
455  {
456  mOutputFile.close();
457  }
458  mFirstFileOutput = true;
459  mMovingAvgScalar = 0;
460  mPrintPeriod = 1;
461  mPrintFormat = SECONDS;
462  mCycleCounter = 0;
463  mFirstCycle = true;
464  }
465 
466  void Profiler::init(double smoothing, const std::string& outputFilename,
467  size_t printPeriod, TimeFormat printFormat)
468  {
469  if (mEnabled)
470  {
471  // Reset everything to its initial state and re-initialize.
472  destroy();
473  std::cout << "[QuickProf] Re-initializing profiler, "
474  << "erasing all profiling blocks" << std::endl;
475  }
476 
477  mEnabled = true;
478 
479  if (smoothing <= 0)
480  {
481  if (smoothing < 0)
482  {
483  printError("Smoothing parameter must be >= 0. Using 0.");
484  }
485 
486  mMovingAvgScalar = 0;
487  }
488  else
489  {
490  // Treat smoothing as a time constant.
491  mMovingAvgScalar = ::exp(-1 / smoothing);
492  }
493 
494  if (!outputFilename.empty())
495  {
496  mOutputFile.open(outputFilename.c_str());
497  }
498 
499  if (printPeriod < 1)
500  {
501  printError("Print period must be >= 1. Using 1.");
502  mPrintPeriod = 1;
503  }
504  else
505  {
506  mPrintPeriod = printPeriod;
507  }
508  mPrintFormat = printFormat;
509 
510  mClock.reset();
511 
512  // Set the start time for the first cycle.
513  mCurrentCycleStartMicroseconds = mClock.getTimeMicroseconds();
514  }
515 
516  void Profiler::beginBlock(const std::string& name)
517  {
518  if (!mEnabled)
519  {
520  return;
521  }
522 
523  if (name.empty())
524  {
525  printError("Cannot allow unnamed profile blocks.");
526  return;
527  }
528 
529  ProfileBlock* block = NULL;
530 
531  std::map<std::string, ProfileBlock*>::iterator iter =
532  mProfileBlocks.find(name);
533  if (mProfileBlocks.end() == iter)
534  {
535  // The named block does not exist. Create a new ProfileBlock.
536  block = new ProfileBlock();
537  mProfileBlocks[name] = block;
538  }
539  else
540  {
541  block = iter->second;
542  }
543 
544  // We do this at the end to get more accurate results.
546  }
547 
548  void Profiler::endBlock(const std::string& name)
549  {
550  if (!mEnabled)
551  {
552  return;
553  }
554 
555  // We do this at the beginning to get more accurate results.
556  unsigned long long int endTick = mClock.getTimeMicroseconds();
557 
558  ProfileBlock* block = getProfileBlock(name);
559  if (!block)
560  {
561  return;
562  }
563 
564  unsigned long long int blockDuration = endTick -
566  block->currentCycleTotalMicroseconds += blockDuration;
567  block->totalMicroseconds += blockDuration;
568  }
569 
571  {
572  if (!mEnabled)
573  {
574  return;
575  }
576 
577  // Update the average total cycle time.
578  // On the first cycle we set the average cycle time equal to the
579  // measured cycle time. This avoids having to ramp up the average
580  // from zero initially.
581  unsigned long long int currentCycleDurationMicroseconds =
582  mClock.getTimeMicroseconds() - mCurrentCycleStartMicroseconds;
583  if (mFirstCycle)
584  {
585  mAvgCycleDurationMicroseconds =
586  (double)currentCycleDurationMicroseconds;
587  }
588  else
589  {
590  mAvgCycleDurationMicroseconds = mMovingAvgScalar *
591  mAvgCycleDurationMicroseconds + (1 - mMovingAvgScalar)
592  * (double)currentCycleDurationMicroseconds;
593  }
594 
595  // Update the average cycle time for each block.
596  std::map<std::string, ProfileBlock*>::iterator blocksBegin =
597  mProfileBlocks.begin();
598  std::map<std::string, ProfileBlock*>::iterator blocksEnd =
599  mProfileBlocks.end();
600  std::map<std::string, ProfileBlock*>::iterator iter = blocksBegin;
601  for (; iter != blocksEnd; ++iter)
602  {
603  ProfileBlock* block = iter->second;
604 
605  // On the first cycle we set the average cycle time equal to the
606  // measured cycle time. This avoids having to ramp up the average
607  // from zero initially.
608  if (mFirstCycle)
609  {
611  (double)block->currentCycleTotalMicroseconds;
612  }
613  else
614  {
615  block->avgCycleTotalMicroseconds = mMovingAvgScalar *
616  block->avgCycleTotalMicroseconds + (1 - mMovingAvgScalar) *
617  (double)block->currentCycleTotalMicroseconds;
618  }
619 
621  }
622 
623  if (mFirstCycle)
624  {
625  mFirstCycle = false;
626  }
627 
628  // If enough cycles have passed, print data to the output file.
629  if (mOutputFile.is_open() && mCycleCounter % mPrintPeriod == 0)
630  {
631  mCycleCounter = 0;
632 
633  if (mFirstFileOutput)
634  {
635  // On the first iteration, print a header line that shows the
636  // names of each data column (i.e. profiling block names).
637  mOutputFile << "# t(s)";
638 
639  std::string suffix = getSuffixString(mPrintFormat);
640  for (iter = blocksBegin; iter != blocksEnd; ++iter)
641  {
642  mOutputFile << " " << (*iter).first << "(" << suffix << ")";
643  }
644 
645  mOutputFile << std::endl;
646  mFirstFileOutput = false;
647  }
648 
649  mOutputFile << getTimeSinceInit(SECONDS) * (double)0.000001;
650 
651  // Print the cycle time for each block.
652  for (iter = blocksBegin; iter != blocksEnd; ++iter)
653  {
654  mOutputFile << " " << getAvgDuration((*iter).first,
655  mPrintFormat);
656  }
657 
658  mOutputFile << std::endl;
659  }
660 
661  ++mCycleCounter;
662  mCurrentCycleStartMicroseconds = mClock.getTimeMicroseconds();
663  }
664 
665  double Profiler::getAvgDuration(const std::string& name,
666  TimeFormat format)const
667  {
668  if (!mEnabled)
669  {
670  return 0;
671  }
672 
673  ProfileBlock* block = getProfileBlock(name);
674  if (!block)
675  {
676  return 0;
677  }
678 
679  double result = 0;
680 
681  switch(format)
682  {
683  case SECONDS:
684  result = block->avgCycleTotalMicroseconds * (double)0.000001;
685  break;
686  case MILLISECONDS:
687  result = block->avgCycleTotalMicroseconds * (double)0.001;
688  break;
689  case MICROSECONDS:
690  result = block->avgCycleTotalMicroseconds;
691  break;
692  case PERCENT:
693  {
694  if (0 == mAvgCycleDurationMicroseconds)
695  {
696  result = 0;
697  }
698  else
699  {
700  result = 100.0 * block->avgCycleTotalMicroseconds /
701  mAvgCycleDurationMicroseconds;
702  }
703  break;
704  }
705  default:
706  break;
707  }
708 
709  return result;
710  }
711 
712  double Profiler::getTotalDuration(const std::string& name,
713  TimeFormat format)
714  {
715  if (!mEnabled)
716  {
717  return 0;
718  }
719 
720  ProfileBlock* block = getProfileBlock(name);
721  if (!block)
722  {
723  return 0;
724  }
725 
726  double blockTotalMicroseconds = (double)block->totalMicroseconds;
727  double result = 0;
728 
729  switch(format)
730  {
731  case SECONDS:
732  result = blockTotalMicroseconds * (double)0.000001;
733  break;
734  case MILLISECONDS:
735  result = blockTotalMicroseconds * (double)0.001;
736  break;
737  case MICROSECONDS:
738  result = blockTotalMicroseconds;
739  break;
740  case PERCENT:
741  {
742  double microsecondsSinceInit = getTimeSinceInit(MICROSECONDS);
743  if (0 == microsecondsSinceInit)
744  {
745  result = 0;
746  }
747  else
748  {
749  result = 100.0 * blockTotalMicroseconds /
750  microsecondsSinceInit;
751  }
752  }
753  break;
754  default:
755  break;
756  }
757 
758  return result;
759  }
760 
762  {
763  double timeSinceInit = 0;
764 
765  switch(format)
766  {
767  case SECONDS:
768  timeSinceInit = (double)mClock.getTimeMicroseconds() * (double)0.000001;
769  break;
770  case MILLISECONDS:
771  timeSinceInit = (double)mClock.getTimeMicroseconds() * (double)0.001;
772  break;
773  case MICROSECONDS:
774  timeSinceInit = (double)mClock.getTimeMicroseconds();
775  break;
776  case PERCENT:
777  {
778  timeSinceInit = 100;
779  break;
780  }
781  default:
782  break;
783  }
784 
785  if (timeSinceInit < 0)
786  {
787  timeSinceInit = 0;
788  }
789 
790  return timeSinceInit;
791  }
792 
793  std::string Profiler::getSummary(TimeFormat format)
794  {
795  if (!mEnabled)
796  {
797  return "";
798  }
799 
800  std::ostringstream oss;
801  std::string suffix = getSuffixString(format);
802 
803  std::map<std::string, ProfileBlock*>::iterator blocksBegin =
804  mProfileBlocks.begin();
805  std::map<std::string, ProfileBlock*>::iterator blocksEnd =
806  mProfileBlocks.end();
807  std::map<std::string, ProfileBlock*>::iterator iter = blocksBegin;
808  for (; iter != blocksEnd; ++iter)
809  {
810  if (iter != blocksBegin)
811  {
812  oss << "\n";
813  }
814 
815  oss << iter->first;
816  oss << ": ";
817  oss << getTotalDuration(iter->first, format);
818  oss << " ";
819  oss << suffix;
820  }
821 
822  return oss.str();
823  }
824 
825  void Profiler::printError(const std::string& msg)const
826  {
827  std::cout << "[QuickProf error] " << msg << std::endl;
828  }
829 
830  ProfileBlock* Profiler::getProfileBlock(const std::string& name)const
831  {
832  std::map<std::string, ProfileBlock*>::const_iterator iter =
833  mProfileBlocks.find(name);
834  if (mProfileBlocks.end() == iter)
835  {
836  // The named block does not exist. Print an error.
837  printError("The profile block named '" + name +
838  "' does not exist.");
839  return NULL;
840  }
841  else
842  {
843  return iter->second;
844  }
845  }
846 
847  std::string Profiler::getSuffixString(TimeFormat format)const
848  {
849  std::string suffix;
850  switch(format)
851  {
852  case SECONDS:
853  suffix = "s";
854  break;
855  case MILLISECONDS:
856  suffix = "ms";
857  break;
858  case MICROSECONDS:
859  suffix = "us";
860  break;
861  case PERCENT:
862  {
863  suffix = "%";
864  break;
865  }
866  default:
867  break;
868  }
869 
870  return suffix;
871  }
872 };
873 
874 #endif
void endBlock(const std::string &name)
Defines the end of the named timing block.
Definition: quickprof.h:548
void init(double smoothing=0.0, const std::string &outputFilename="", size_t printPeriod=1, TimeFormat printFormat=MILLISECONDS)
Initializes the profiler.
Definition: quickprof.h:466
TimeFormat
A set of ways to represent timing results.
Definition: quickprof.h:203
std::string getSummary(TimeFormat format=PERCENT)
Returns a summary of total times in each block.
Definition: quickprof.h:793
Definition: quickprof.h:205
Definition: quickprof.h:206
unsigned long long int getTimeMicroseconds()
Returns the time in us since the last call to reset or since the Clock was created.
Definition: quickprof.h:123
double getTimeSinceInit(TimeFormat format)
Computes the elapsed time since the profiler was initialized.
Definition: quickprof.h:761
double getAvgDuration(const std::string &name, TimeFormat format) const
Returns the average time used in the named block per profiling cycle.
Definition: quickprof.h:665
static Profiler & instance()
Accesses the singleton instance.
Definition: quickprof.h:437
double avgCycleTotalMicroseconds
The accumulated time (in us) spent in this block during the past profiling cycle. ...
Definition: quickprof.h:78
Definition: quickprof.h:208
void reset()
Resets the initial reference time.
Definition: quickprof.h:104
void beginBlock(const std::string &name)
Begins timing the named block of code.
Definition: quickprof.h:516
A simple data structure representing a single timed block of code.
Definition: quickprof.h:59
unsigned long long int totalMicroseconds
The total accumulated time (in us) spent in this block.
Definition: quickprof.h:81
double getTotalDuration(const std::string &name, TimeFormat format)
Returns the total time spent in the named block since the profiler was initialized.
Definition: quickprof.h:712
Profiler()
Useful for creating multiple Profiler instances.
Definition: quickprof.h:416
void endCycle()
Defines the end of a profiling cycle.
Definition: quickprof.h:570
unsigned long long int currentBlockStartMicroseconds
The starting time (in us) of the current block update.
Definition: quickprof.h:70
unsigned long long int currentCycleTotalMicroseconds
The accumulated time (in us) spent in this block during the current profiling cycle.
Definition: quickprof.h:74
Definition: quickprof.h:207
double min(const matrix::Matrix &v)
returns the smallest element
Definition: controller_misc.cpp:307
~Profiler()
Definition: quickprof.h:429
Clock()
Definition: quickprof.h:89
A singleton class that manages timing for a set of profiling blocks.
Definition: quickprof.h:212
~Clock()
Definition: quickprof.h:97
ProfileBlock()
Definition: quickprof.h:61
A cross-platform clock class inspired by the Timer classes in Ogre (http://www.ogre3d.org).
Definition: quickprof.h:86