Sunday, January 31, 2010

Cross-platform Code Profiling

In order to guide optimization efforts, it is often necessary to determine how long individual blocks of code take to execute. Although there are a number of packages available that do this, I have found them to generally i) be quite expensive, ii) be inconvenient to use and iii) generate huge output files. This is not to say these packages don't have a place, but simply that sometimes you don't need all their features and so a more compact approach would be useful.

The classes presented here are simply included in you project and compiled in. Blocks are instrumented manually with pre-processor macros that initialize and register timers. Timing is performed with QueryPerformanceCounter on Windows and gettimeofday on Linux/Mac, giving an approximate lower bound on the intervals that can be resolved of about 1 microsecond. If you need more resolution than this, you'll have to use something else. Statistics can then be dumped to any std::ostream, allowing you to print profiling statistics to a file, the console, log window or whatever. The only statistics collected are the call count for each block, average time per call and total elapse time in the block.

Here is an example of how to use them:


// comment this out to turn off profiling
// (and avoid its associated cost)


int main( int argc, char **argv ){
 PROFILER_START( main_timer );

 // do stuff here

 PROFILER_END( main_timer );
 ProfileManager::Get()->PrintStatistics( std::cout );
 return 0;

Here are the source files. You can use them under a BSD license. If you find them useful I'd appreciate if you let me know.


No comments: