Homepage Demos Overview Downloads Tutorials Reference
Credits

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:

  • Use a static variable to hold an id number for the code section (doesn't necessarily have to be static, but is faster that way)
  • Create a Profiler::Timer object - its construction marks the 'start' time, and its destructor marks the 'stop' time.

  ProfilerOfSize<2> prof; //A global manager for all the sections
  
  void f() {
    static unsigned int id=prof.getNewID("f"); // <== Get the ID number 
    Profiler::Timer timer(id,&prof);           // <== start the timer
    //...
    if(rand()>RAND_MAX/2)
      return; // destruction of timer occurs automatically!
    //...
  } // if we didn't hit the return, timer will otherwise destruct here!

However, there's a macro that makes this a one liner:

  void g() {
    PROFSECTION("g",prof);   // <== Most of the time, this is all you need
    //...                    // (unless you're 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:

  • Processes can read each other's Profilers - so must be able to live in shared memory
    This is so one process can generate a report on performance of the entire system at once
  • Flexible memory footprint
    MainObject will probably have a lot of subsections. MotionObject won't. Since SectionInfo takes some significant memory space, we don't want to force MotionObject to needlessly make a lot of them.
  • Flexible usage - can have a single generic global, as well as creating multiple
  • Fast - don't want to kill performance of profiled sections, or throw off reported results

Consessions made:

  • Sections are not dynamically allocated
  • Sections within a Profiler are mutually exclusive (otherwise curSection won't be reliable)
  • Results don't try to take affects of pre-emptive multitasking into account.

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:
This could be made much prettier if we didn't care about the virtual function-shared memory problems... sigh

Definition at line 87 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 = 75
 maximum length of names of timers
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 = offsetof(ProfilerOfSize<1>,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 115 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 141 of file Profiler.cc.

Referenced by Profiler::Timer::~Timer().

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 174 of file Profiler.h.

Referenced by finished(), and setCurrent().

float* Profiler::getBuckets  )  [inline]
 

returns the bucket boundaries

Definition at line 145 of file Profiler.h.

SectionInfo* Profiler::getInfos  )  [inline]
 

gets the actual storage area of the SectionInfo's

Definition at line 160 of file Profiler.h.

Referenced by finished(), getNewID(), report(), reset(), and setCurrent().

unsigned int Profiler::getNewID const char *  name  ) 
 

call this to get a new ID number

Definition at line 58 of file Profiler.cc.

Referenced by MMCombo::ReadySendJoints().

void Profiler::initBuckets  )  [static]
 

called during process init (before any profiled sections)

Definition at line 52 of file Profiler.cc.

Referenced by MMCombo::MMCombo().

std::string Profiler::report  ) 
 

outputs profiling information

Definition at line 71 of file Profiler.cc.

Referenced by ProfilerCheckControl::activate().

void Profiler::reset  ) 
 

resets profiling information

Definition at line 108 of file Profiler.cc.

void Profiler::setCurrent Timer tr  )  [protected]
 

called automatically by Timer() - sets the current timer

Definition at line 120 of file Profiler.cc.

Referenced by Profiler::Timer::setID(), and Profiler::Timer::Timer().


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 167 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.

Referenced by initBuckets(), and report().

unsigned int Profiler::curSection
 

the current timer

Definition at line 153 of file Profiler.h.

Referenced by finished(), and setCurrent().

float Profiler::gamma
 

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

Definition at line 155 of file Profiler.h.

Referenced by finished(), and setCurrent().

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.

Referenced by initBuckets().

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

number of slots in the histograms

Definition at line 92 of file Profiler.h.

Referenced by finished(), initBuckets(), and setCurrent().

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

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

Definition at line 94 of file Profiler.h.

Referenced by initBuckets().

unsigned int Profiler::infosOffset = offsetof(ProfilerOfSize<1>,infos) [static, protected]
 

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

Definition at line 9 of file Profiler.cc.

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

maximum length of names of timers

Definition at line 90 of file Profiler.h.

Referenced by getNewID().

const unsigned int Profiler::maxSections
 

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

Definition at line 156 of file Profiler.h.

Referenced by getNewID().

unsigned int Profiler::sectionsUsed
 

the number of timer IDs which have been assigned

Definition at line 157 of file Profiler.h.

Referenced by getNewID().

TimeET Profiler::startTime
 

time of beginning profiling

Definition at line 154 of file Profiler.h.

Referenced by report(), and reset().


The documentation for this class was generated from the following files:

Tekkotsu v2.2.1
Generated Tue Nov 23 16:37:50 2004 by Doxygen 1.3.9.1