Fastest timing resolution system

I recently had this question and did some research. The good news is that all three of the major operating systems provide some sort of high resolution timer. The bad news is that it is a different API call on each system. For POSIX operating systems you want to use clock_gettime(). If you're on Mac OS X, however, this is not supported, you have to use mach_get_time(). For windows, use QueryPerformanceCounter. Alternatively, with compilers that support OpenMP, you can use omp_get_wtime(), but it may not provide the resolution that you are looking for.

I also found cycle.h from fftw.org (www.fftw.org/cycle.h) to be useful.

Here is some code that calls a timer on each OS, using some ugly #ifdef statements. The usage is very simple: Timer t; t.tic(); SomeOperation(); t.toc("Message"); And it will print out the elapsed time in seconds.

#ifndef TIMER_H
#define TIMER_H

#include <iostream>
#include <string>
#include <vector>

# if  (defined(__MACH__) && defined(__APPLE__))
#   define _MAC
# elif (defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(_WIN64))
#   define _WINDOWS
#   ifndef WIN32_LEAN_AND_MEAN
#     define WIN32_LEAN_AND_MEAN
#   endif
#endif

# if defined(_MAC)
#    include <mach/mach_time.h>
# elif defined(_WINDOWS)
#    include <windows.h>
# else
#    include <time.h>
# endif


#if defined(_MAC)
  typedef uint64_t timer_t;
  typedef double   timer_c;

#elif defined(_WINDOWS)
  typedef LONGLONG      timer_t;
  typedef LARGE_INTEGER timer_c;

#else
  typedef double   timer_t;
  typedef timespec timer_c;
#endif

  //==============================================================================
  // Timer
  // A quick class to do benchmarking.
  // Example: Timer t;  t.tic();  SomeSlowOp(); t.toc("Some Message");

  class Timer {
  public:
    Timer();

    inline void tic();
    inline void toc();
    inline void toc(const std::string &msg);

    void print(const std::string &msg);
    void print();
    void reset();
    double getTime();

  private:
    timer_t start;
    double duration;
    timer_c ts;
    double conv_factor;
    double elapsed_time;
  };



  Timer::Timer() {

#if defined(_MAC)
    mach_timebase_info_data_t info;
    mach_timebase_info(&info);

    conv_factor = (static_cast<double>(info.numer))/
                  (static_cast<double>(info.denom));
    conv_factor = conv_factor*1.0e-9;

#elif defined(_WINDOWS)
    timer_c freq;
    QueryPerformanceFrequency(&freq);
    conv_factor = 1.0/(static_cast<double>freq.QuadPart);

#else
    conv_factor = 1.0;
#endif

    reset();
  }

  inline void Timer::tic() {

#if defined(_MAC)
    start = mach_absolute_time();

#elif defined(_WINDOWS)
    QueryPerformanceCounter(&ts);
    start = ts.QuadPart;

#else
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
    start = static_cast<double>(ts.tv_sec) + 1.0e-9 *
            static_cast<double>(ts.tv_nsec);

#endif
  }

  inline void Timer::toc() {
#if defined(_MAC)
    duration =  static_cast<double>(mach_absolute_time() - start);

#elif defined(_WINDOWS)
    QueryPerformanceCounter(&qpc_t);
    duration = static_cast<double>(qpc_t.QuadPart - start);

#else
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
    duration = (static_cast<double>(ts.tv_sec) + 1.0e-9 *
                static_cast<double>(ts.tv_nsec)) - start;

#endif

    elapsed_time = duration*conv_factor;
  }

  inline void Timer::toc(const std::string &msg) { toc(); print(msg); };

  void Timer::print(const std::string &msg) {
    std::cout << msg << " "; print();
  }

  void Timer::print() {
    if(elapsed_time) {
      std::cout << "elapsed time: " << elapsed_time << " seconds\n";
    }
  }

  void Timer::reset() { start = 0; duration = 0; elapsed_time = 0; }
  double Timer::getTime() { return elapsed_time; }


#if defined(_WINDOWS)
# undef WIN32_LEAN_AND_MEAN
#endif

#endif // TIMER_H

For timing, the current Microsoft recommendation is to use QueryPerformanceCounter & QueryPerformanceFrequency.

This will give you better-than-millisecond timing. If the system doesn't support a high-resolution timer, then it will default to milliseconds (the same as GetTickCount).

Here is a short Microsoft article with examples of why you should use it :)

Tags:

Windows

Time

C++

C