High-resolution timer for C++


Howdy ho! My name is Simon Wybranski, I am a developer on the C++ AMP team!

In this blog post I am going to present a high-resolution timer for measuring the performance of C++ AMP algorithms. There is nothing specific in it to C++ AMP, so it can be used to measure elapsed time of your PPL algorithms or any other C++ code.

Listing of timer.h:

 1: #pragma once
 2: #include <windows.h>
 3:  
 4: struct Timer
 5: {
 6:     void Start() 
 7:     {
 8:         QueryPerformanceCounter(&m_start);
 9:     }
 10:  
 11:     void Stop() 
 12:     {
 13:         QueryPerformanceCounter(&m_stop);
 14:     }
 15:     
 16:     // Returns elapsed time in milliseconds (ms)
 17:     double Elapsed()
 18:     {
 19:         return (m_stop.QuadPart - m_start.QuadPart - m_overhead) \
 20:                                           * 1000.0 / m_freq.QuadPart;
 21:     }
 22:  
 23: private:
 24:  
 25:     // Returns the overhead of the timer in ticks
 26:     static LONGLONG GetOverhead()
 27:     {
 28:         Timer t;
 29:         t.Start();
 30:         t.Stop();
 31:         return t.m_stop.QuadPart - t.m_start.QuadPart;
 32:     }
 33:  
 34:     LARGE_INTEGER m_start;
 35:     LARGE_INTEGER m_stop;
 36:     static LARGE_INTEGER m_freq;
 37:     static LONGLONG m_overhead;
 38: };

 

Listing of timer.cpp:

 1: #include "timer.h"
 2:  
 3: // Initialize the resolution of the timer
 4: LARGE_INTEGER Timer::m_freq = \
 5:           (QueryPerformanceFrequency(&Timer::m_freq), Timer::m_freq);
 6:  
 7: // Calculate the overhead of the timer
 8: LONGLONG Timer::m_overhead = Timer::GetOverhead();

 

Snippet showing the usage:

 1: Timer t; 
 2: t.Start(); 
 3: // Your algorithm goes here 
 4: t.Stop(); 
 5:  
 6: std::cout << t.Elapsed() << " ms" << std::endl; 

 

Enjoy!!

timer.zip

Comments (6)

  1. Saphira says:

    This seems a very naive example of using the a timer which disrespects Microsoft's own advice about jumps in the timer and multiple CPUs.

  2. Matthew - Developer says:

    Please checkout this MSDN article regarding high performance timers if you want to get serious with high perf timers:

    msdn.microsoft.com/…/cc163996.aspx

  3. Hi Saphira,

    You are right, it is a simple wrapper class over QPC() API. It met my needs, but certainly might be not good everyone. You can adapt it to account for possible jumps and multiprocessor system with these changes:

    1) Call SetThreadAffinityMask in the constructor, constraint thread to run on the same processor.

    2) Call GetTickCount() in Start() and Stop() member functions, use these measurements to detect possible jump when Elapsed() is called. Here is a code example for that: msdn.microsoft.com/…/ms724408(v=vs.85).aspx

    Finally, please check the link that Matthew shared in his comment for more advanced timer that might suit you better.

  4. Klaim says:

    Hi

    Why not use std::chrono?

    As far as I understand, the high precision clock implementation on windows would use QueryPerformance functions but would do it hidden and in a cross-platform way.

    Is there something I'm missing?

    Thanks.

  5. Well, <chrono> is not available in VC10 SP1.

    Using <chrono>'s high_resolution_clock should give portable code access to the platform's highest quality implementation. Currently, the VC11 Developer Preview's implementation doesn't use QueryPerformanceCounter(), but it should. This is tracked by connect.microsoft.com/…/c-chrono-headers-high-resolution-clock-does-not-have-high-resolution , assigned to myself. I can't promise anything, but I would like to fix this before VC11 RTM.

  6. Yo! says:

    How about a simple <pre></pre> for code?  The way you have it, well, try to copy and paste it.

Skip to main content