38 #if defined(WIN32) || defined(_WIN32)
39 #define USE_WINDOWS_TIMERS
52 #define PROFILER quickprof::Profiler::instance()
91 #ifdef USE_WINDOWS_TIMERS
92 QueryPerformanceFrequency(&mClockFrequency);
106 #ifdef USE_WINDOWS_TIMERS
107 QueryPerformanceCounter(&mStartTime);
108 mStartTick = GetTickCount();
109 mPrevClockCycles = 0;
111 gettimeofday(&mStartTime, NULL);
125 #ifdef USE_WINDOWS_TIMERS
130 LARGE_INTEGER currentTime;
131 QueryPerformanceCounter(¤tTime);
132 LONGLONG clockCycles = currentTime.QuadPart -
137 LONGLONG sec = clockCycles / mClockFrequency.QuadPart;
145 LONGLONG msec1 = sec * 1000 + (clockCycles - sec *
146 mClockFrequency.QuadPart) * 1000 / mClockFrequency.QuadPart;
147 DWORD tickCount = GetTickCount();
148 if (tickCount < mStartTick)
150 mStartTick = tickCount;
152 LONGLONG msec2 = (LONGLONG)(tickCount - mStartTick);
153 LONGLONG msecDiff = msec1 - msec2;
154 if (msecDiff < -100 || msecDiff > 100)
157 LONGLONG adjustment = (
std::min)(msecDiff *
158 mClockFrequency.QuadPart / 1000, clockCycles -
160 mStartTime.QuadPart += adjustment;
161 clockCycles -= adjustment;
164 sec = clockCycles / mClockFrequency.QuadPart;
169 LONGLONG usec = (clockCycles - sec * mClockFrequency.QuadPart) *
170 1000000 / mClockFrequency.QuadPart;
174 mPrevClockCycles = clockCycles;
178 return sec * 1000000 + usec;
183 struct timeval currentTime;
184 gettimeofday(¤tTime, NULL);
185 return (
unsigned long long int)(currentTime.tv_sec -
186 mStartTime.tv_sec) * 1000000 + (currentTime.tv_usec -
192 #ifdef USE_WINDOWS_TIMERS
193 LARGE_INTEGER mClockFrequency;
195 LONGLONG mPrevClockCycles;
196 LARGE_INTEGER mStartTime;
198 struct timeval mStartTime;
275 inline void init(
double smoothing=0.0,
276 const std::string& outputFilename=
"",
size_t printPeriod=1,
284 inline void beginBlock(
const std::string& name);
291 inline void endBlock(
const std::string& name);
351 inline void destroy();
358 inline void printError(
const std::string& msg)
const;
366 inline ProfileBlock* getProfileBlock(
const std::string& name)
const;
373 inline std::string getSuffixString(
TimeFormat format)
const;
382 unsigned long long int mCurrentCycleStartMicroseconds;
387 double mAvgCycleDurationMicroseconds;
390 std::map<std::string, ProfileBlock*> mProfileBlocks;
393 std::ofstream mOutputFile;
396 bool mFirstFileOutput;
400 double mMovingAvgScalar;
410 size_t mCycleCounter;
419 mCurrentCycleStartMicroseconds = 0;
420 mAvgCycleDurationMicroseconds = 0;
421 mFirstFileOutput =
true;
422 mMovingAvgScalar = 0;
443 void Profiler::destroy()
447 mCurrentCycleStartMicroseconds = 0;
448 mAvgCycleDurationMicroseconds = 0;
449 while (!mProfileBlocks.empty())
451 delete (*mProfileBlocks.begin()).second;
452 mProfileBlocks.erase(mProfileBlocks.begin());
454 if (mOutputFile.is_open())
458 mFirstFileOutput =
true;
459 mMovingAvgScalar = 0;
473 std::cout <<
"[QuickProf] Re-initializing profiler, "
474 <<
"erasing all profiling blocks" << std::endl;
483 printError(
"Smoothing parameter must be >= 0. Using 0.");
486 mMovingAvgScalar = 0;
491 mMovingAvgScalar = ::exp(-1 / smoothing);
494 if (!outputFilename.empty())
496 mOutputFile.open(outputFilename.c_str());
501 printError(
"Print period must be >= 1. Using 1.");
506 mPrintPeriod = printPeriod;
508 mPrintFormat = printFormat;
525 printError(
"Cannot allow unnamed profile blocks.");
531 std::map<std::string, ProfileBlock*>::iterator iter =
532 mProfileBlocks.find(name);
533 if (mProfileBlocks.end() == iter)
537 mProfileBlocks[name] = block;
541 block = iter->second;
564 unsigned long long int blockDuration = endTick -
581 unsigned long long int currentCycleDurationMicroseconds =
585 mAvgCycleDurationMicroseconds =
586 (double)currentCycleDurationMicroseconds;
590 mAvgCycleDurationMicroseconds = mMovingAvgScalar *
591 mAvgCycleDurationMicroseconds + (1 - mMovingAvgScalar)
592 * (
double)currentCycleDurationMicroseconds;
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)
629 if (mOutputFile.is_open() && mCycleCounter % mPrintPeriod == 0)
633 if (mFirstFileOutput)
637 mOutputFile <<
"# t(s)";
639 std::string suffix = getSuffixString(mPrintFormat);
640 for (iter = blocksBegin; iter != blocksEnd; ++iter)
642 mOutputFile <<
" " << (*iter).first <<
"(" << suffix <<
")";
645 mOutputFile << std::endl;
646 mFirstFileOutput =
false;
652 for (iter = blocksBegin; iter != blocksEnd; ++iter)
658 mOutputFile << std::endl;
694 if (0 == mAvgCycleDurationMicroseconds)
701 mAvgCycleDurationMicroseconds;
732 result = blockTotalMicroseconds * (double)0.000001;
735 result = blockTotalMicroseconds * (double)0.001;
738 result = blockTotalMicroseconds;
743 if (0 == microsecondsSinceInit)
749 result = 100.0 * blockTotalMicroseconds /
750 microsecondsSinceInit;
763 double timeSinceInit = 0;
785 if (timeSinceInit < 0)
790 return timeSinceInit;
800 std::ostringstream oss;
801 std::string suffix = getSuffixString(format);
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)
810 if (iter != blocksBegin)
825 void Profiler::printError(
const std::string& msg)
const
827 std::cout <<
"[QuickProf error] " << msg << std::endl;
830 ProfileBlock* Profiler::getProfileBlock(
const std::string& name)
const
832 std::map<std::string, ProfileBlock*>::const_iterator iter =
833 mProfileBlocks.find(name);
834 if (mProfileBlocks.end() == iter)
837 printError(
"The profile block named '" + name +
838 "' does not exist.");
847 std::string Profiler::getSuffixString(
TimeFormat format)
const
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