Homepage Demos Overview Downloads Tutorials Reference
Credits
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members | Related Pages | Search

Profiler Class Reference

#include <Profiler.h>

Inheritance diagram for Profiler:

Inheritance graph
[legend]
List of all members.

Detailed Description

Managers a hierarchy of timers for profiling time spent in code, gives microsecond resolution.

Doesn't use any pointers so it's safe to put this in shared memory regions.
That's handy so one process can collate all the profiling information across processes to give a summary report to the user.

Example usage: (two different methods, f() or g())

  ProfilerOfSize<2> prof; //A global manager for all the sections
  
  void f() {
    static unsigned int id=prof.getNewID("f"); // *** YOU NEED THIS LINE for each section to profile
    Profiler::Timer timer(id,&prof);           // *** YOU NEED THIS LINE for each section to profile
    //...
    if(rand()>RAND_MAX/2)
      return; // destruction of timer occurs automatically!
    //...
  } // if we didn't hit the return, timer will otherwise destruct here!
  
  void g() {
    PROFSECTION("g",prof);   // Could also use this macro instead (recommended if you're
    //...                    // not doing something fancy like conditional timers)
    f(); // will note f's time as g's child time
    //...
  }
The idea is similar to that used by MMAccessor. If you want to profile a section at smaller resolution than a function, you can use tricks shown in MMAccessor's documentation to limit the timer's scope.

Here were the constraints I set for myself:

Consessions made:

Global readability is first priority since generating reports is the primary usage, thus we have to be able to handle being in shared memory space. This means no virtual functions and no pointer storage. Unfortunately, this makes the second constraint rather difficult.
Run-time dynamic allocation is right out. But the number of sections is set at compile time anyway, so it should be OK to set this at compile time, using a template parameter.
That gets us 99% of the way there, but it can be burdensome to use this since the template means there's no consistant type for all profilers - you can't have a generic Profiler type if it's templated - you would have to know the size of the profiler you're referring to.
That kind of brings in the third constraint... Instead of accepting a single global, I decided to make a general base (Profiler) and then a templated subclass to hold the bulk data section. This has the nice side affect of not having to specify the bulk of the code in the header, but has the downside that accessing the info stored in the subclass from the super class is very much a hack. If you think you can get around this, good luck!

Note:
~Profiler() isn't virtual - that's on purpose.
This could be made much prettier if we didn't care about the virtual function-shared memory problems... sigh

Definition at line 80 of file Profiler.h.

Public Member Functions

unsigned int getNewID (const char *name)
 call this to get a new ID number

float * getBuckets ()
 returns the bucket boundaries

std::string report ()
 outputs profiling information

void reset ()
 resets profiling information

SectionInfogetInfos ()
 gets the actual storage area of the SectionInfo's


Static Public Member Functions

void initBuckets ()
 called during process init (before any profiled sections)


Public Attributes

unsigned int curSection
 the current timer

TimeET startTime
 time of beginning profiling

float gamma
 gamma to use with exponential averages (1 to freeze, 0 to set to last)

const unsigned int maxSections
 so we can read the size of the infos array back again at runtime

unsigned int sectionsUsed
 the number of timer IDs which have been assigned


Static Public Attributes

const unsigned int MaxSectionNameLen = 32
 maximum length of names of timers, 32 chosen to make nice memory alignment

const unsigned int HistSize = 32
 number of slots in the histograms

const unsigned int HistTime = 10*1000
 the upper bound (exclusive) of the histograms, in milliseconds.

const float HistCurve = 4.05
 affects how linearly the buckets are distributed - 1 means linear, >1 causes higher resolution for short times


Protected Member Functions

 Profiler (unsigned int mx)
 constructor, protected because you don't want to construct one of these - use ProfilerOfSize<x>!

void setCurrent (Timer &tr)
 called automatically by Timer() - sets the current timer

void finished (Timer &tr)
 called automatically by ~Timer() - notes the specified timer as finished (doesn't check if the timer is actually the current one - don't screw up!)

unsigned int getBucket (float t)
 returns which bucket a time should go in, does a binary search over buckets (unless someone things a log() call would be faster...)


Static Protected Attributes

float buckets [HistSize]
 holds boundaries for each bucket

unsigned int infosOffset = reinterpret_cast<unsigned int>((static_cast<ProfilerOfSize<1>*>(NULL))->infos)
 NASTY HACK - this is how we get around using virtual functions.


Friends

class Timer
 Only the Timer's should be calling setCurrent() and finished() upon the Timer's construction and destruction.


Constructor & Destructor Documentation

Profiler::Profiler unsigned int  mx  )  [protected]
 

constructor, protected because you don't want to construct one of these - use ProfilerOfSize<x>!

Definition at line 114 of file Profiler.cc.


Member Function Documentation

void Profiler::finished Timer tr  )  [protected]
 

called automatically by ~Timer() - notes the specified timer as finished (doesn't check if the timer is actually the current one - don't screw up!)

Definition at line 140 of file Profiler.cc.

References Profiler::Timer::_id, Profiler::Timer::_parent, Profiler::SectionInfo::calls, curSection, Profiler::Timer::elapsed(), Profiler::SectionInfo::execExpAvg, Profiler::SectionInfo::execHist, gamma, getBucket(), getInfos(), HistSize, HistTime, Profiler::SectionInfo::totalTime, and TimeET::Value().

unsigned int Profiler::getBucket float  t  )  [inline, protected]
 

returns which bucket a time should go in, does a binary search over buckets (unless someone things a log() call would be faster...)

Definition at line 167 of file Profiler.h.

References buckets, and HistSize.

float* Profiler::getBuckets  )  [inline]
 

returns the bucket boundaries

Definition at line 138 of file Profiler.h.

References buckets.

SectionInfo* Profiler::getInfos  )  [inline]
 

gets the actual storage area of the SectionInfo's

Definition at line 153 of file Profiler.h.

References infosOffset.

unsigned int Profiler::getNewID const char *  name  ) 
 

call this to get a new ID number

Definition at line 57 of file Profiler.cc.

References ASSERTRETVAL, getInfos(), MaxSectionNameLen, maxSections, Profiler::SectionInfo::name, and sectionsUsed.

void Profiler::initBuckets  )  [static]
 

called during process init (before any profiled sections)

Definition at line 51 of file Profiler.cc.

References buckets, HistCurve, HistSize, and HistTime.

std::string Profiler::report  ) 
 

outputs profiling information

Definition at line 70 of file Profiler.cc.

References buckets, Profiler::SectionInfo::calls, getInfos(), HistSize, sectionsUsed, startTime, and TimeET::Value().

void Profiler::reset  ) 
 

resets profiling information

Definition at line 107 of file Profiler.cc.

References getInfos(), Profiler::SectionInfo::reset(), sectionsUsed, TimeET::Set(), and startTime.

void Profiler::setCurrent Timer tr  )  [protected]
 

called automatically by Timer() - sets the current timer

Definition at line 119 of file Profiler.cc.

References Profiler::Timer::_id, Profiler::Timer::_parent, Profiler::Timer::_t, TimeET::Age(), Profiler::SectionInfo::calls, curSection, gamma, getBucket(), getInfos(), HistSize, HistTime, Profiler::SectionInfo::interExpAvg, Profiler::SectionInfo::interHist, Profiler::SectionInfo::lastTime, TimeET::Set(), Profiler::SectionInfo::totalInterval, and TimeET::Value().


Friends And Related Function Documentation

friend class Timer [friend]
 

Only the Timer's should be calling setCurrent() and finished() upon the Timer's construction and destruction.

Definition at line 160 of file Profiler.h.


Member Data Documentation

float Profiler::buckets [static, protected]
 

holds boundaries for each bucket

Definition at line 6 of file Profiler.cc.

unsigned int Profiler::curSection
 

the current timer

Definition at line 146 of file Profiler.h.

float Profiler::gamma
 

gamma to use with exponential averages (1 to freeze, 0 to set to last)

Definition at line 148 of file Profiler.h.

const float Profiler::HistCurve = 4.05 [static]
 

affects how linearly the buckets are distributed - 1 means linear, >1 causes higher resolution for short times

Definition at line 4 of file Profiler.cc.

const unsigned int Profiler::HistSize = 32 [static]
 

number of slots in the histograms

Definition at line 85 of file Profiler.h.

const unsigned int Profiler::HistTime = 10*1000 [static]
 

the upper bound (exclusive) of the histograms, in milliseconds.

Definition at line 87 of file Profiler.h.

unsigned int Profiler::infosOffset = reinterpret_cast<unsigned int>((static_cast<ProfilerOfSize<1>*>(NULL))->infos) [static, protected]
 

NASTY HACK - this is how we get around using virtual functions.

Definition at line 8 of file Profiler.cc.

const unsigned int Profiler::MaxSectionNameLen = 32 [static]
 

maximum length of names of timers, 32 chosen to make nice memory alignment

Definition at line 83 of file Profiler.h.

const unsigned int Profiler::maxSections
 

so we can read the size of the infos array back again at runtime

Definition at line 149 of file Profiler.h.

unsigned int Profiler::sectionsUsed
 

the number of timer IDs which have been assigned

Definition at line 150 of file Profiler.h.

TimeET Profiler::startTime
 

time of beginning profiling

Definition at line 147 of file Profiler.h.


The documentation for this class was generated from the following files:
Tekkotsu v1.4
Generated Sat Jul 19 00:09:07 2003 by Doxygen 1.3.2