1. Computing
Send to a Friend via Email

How do I do High Resolution Timing in C++ on Windows?

A Very Accurate Timer

By

How do I time My C++ Code? This is for Windows (2000, XP and Vista- It's untested on Vista).

Especially when having a go at Programming Challenges, it can be vital to know how long a function or an algorithm takes to run. In the Intel and AMD CPus there is a high speed counter. It increments at a rate of billions per second- the exact rate depends upon the clock speed but it is very fast. The Windows API includes function calls to read the value of this counter and also the frequency of the counter- ie how many times per second it is counting. So to time code with accuracy of microseconds- the functions listed below can be used.

How It Works

If we take two readings at TimeStart and then TimeEnd then the difference is the number of counts. Divide this by the frequency of the counter- a value expressed as ticks per second and the result is the length of time that the timed code took to execute.

The variables that are returned from the system calls

   QueryPerformanceFrequency( &frequency ) ;
   QueryPerformanceCounter(&timer->start) ;
 
are both 64 bit values. I used Visual C++ 6.0 to compile this code and used the type LARGE_INTEGER for portability. (The underlying type is the Microsoft __int64 type).

LARGE_INTEGER is defined as

 typedef union _LARGE_INTEGER {
     struct {
         DWORD LowPart;
         LONG HighPart;
     };
     LONGLONG QuadPart; 
 } LARGE_INTEGER;
 
Of course when doing the division, the two values are cast to doubles before the division, otherwise the division will be done as a 64 bit integer division with no fractional part.

How To do the Timing

Declare a variable of class CStopWatch eg s. Then before the code you wish to time, insert a s.startTimer() function method call and after the code, a s.stopTimer() call. You can then call s.getElapsedTime() to return the time in seconds accurate to microseconds.

When doing timing or benchmarking of code, you should do a number of runs and take the average time- because of other processes running under Windows, how much swapping to disk is occurring etc, the values between two runs may vary. A good tip is to reboot before the timings. That way there are fewer programs running and RAM is less likely to be fragmented.

Listing of C++ Timing Code

There is a header file hr_time.h and it's body hr_time.cpp hr_time.h
 #include <windows.h>
 
 typedef struct {
     LARGE_INTEGER start;
     LARGE_INTEGER stop;
 } stopWatch;
 
 class CStopWatch {
 
 private:
     stopWatch timer;
     LARGE_INTEGER frequency;
     double LIToSecs( LARGE_INTEGER & L) ;
 public:
     CStopWatch() ;
     void startTimer( ) ;
     void stopTimer( ) ;
     double getElapsedTime() ;
 };
 
hr_time.cpp
 #include <windows.h>
 
 #ifndef hr_timer
 #include "hr_time.h"
 #define hr_timer
 #endif
 
 double CStopWatch::LIToSecs( LARGE_INTEGER & L) {
     return ((double)L.QuadPart /(double)frequency.QuadPart) ;
 }
 
 CStopWatch::CStopWatch(){
     timer.start.QuadPart=0;
     timer.stop.QuadPart=0; 
     QueryPerformanceFrequency( &frequency ) ;
 }
 
 void CStopWatch::startTimer( ) {
     QueryPerformanceCounter(&timer.start) ;
 }
 
 void CStopWatch::stopTimer( ) {
     QueryPerformanceCounter(&timer.stop) ;
 }
 
 double CStopWatch::getElapsedTime() {
     LARGE_INTEGER time;
     time.QuadPart = timer.stop.QuadPart - timer.start.QuadPart;
     return LIToSecs( time) ;
 }
 
In comparison with the C code, I moved the call to get the CPU frequency into the class constructor. This is a constant value (hopefully!) so it makes sense to read it once, rather than keep requesting it.

©2014 About.com. All rights reserved.