# Cross-Platform High-Performance timing?

## Recommended Posts

I was wondering if there's a cross-platform wrapper around high-performance timers like QueryPerfomanceTimer on windows, and whatever is used for that on linuxes. I did a search but couldn't find any.

##### Share on other sites
I know about Boost::Timer, but I don't know its resolution...

##### Share on other sites
glfw comes also with some timing functions. I have just looked into its source code and on windows it seems to use QueryPerformanceCounter if available with a fall-back to timeGetTime. On Linux and Mac it uses gettimeofday.

##### Share on other sites
Thanks for your replies. Boost::Timer I knew of, but it seems low-resolution. GLFW I also knew of, but for some reason I wasn't using the high-precision timing stuff, only low-precision, so hadn't realized it had that as well.

##### Share on other sites
Take a look at SDL_GetTicks source code.

##### Share on other sites
Quote:
 Take a look at SDL_GetTicks source code.

You mean
voidSDL_StartTicks(void){    /* Set first ticks value */#ifdef USE_GETTICKCOUNT    start = GetTickCount();#else#if 0                           /* Apparently there are problems with QPC on Win2K */    if (QueryPerformanceFrequency(&hires_ticks_per_second) == TRUE) {        hires_timer_available = TRUE;        QueryPerformanceCounter(&hires_start_ticks);    } else#endif    {        hires_timer_available = FALSE;        timeBeginPeriod(1);     /* use 1 ms timer precision */        start = timeGetTime();    }#endif}Uint32SDL_GetTicks(void){    DWORD now, ticks;#ifndef USE_GETTICKCOUNT    LARGE_INTEGER hires_now;#endif#ifdef USE_GETTICKCOUNT    now = GetTickCount();#else    if (hires_timer_available) {        QueryPerformanceCounter(&hires_now);        hires_now.QuadPart -= hires_start_ticks.QuadPart;        hires_now.QuadPart *= 1000;        hires_now.QuadPart /= hires_ticks_per_second.QuadPart;        return (DWORD) hires_now.QuadPart;    } else {        now = timeGetTime();    }#endif    if (now < start) {        ticks = (TIME_WRAP_VALUE - start) + now;    } else {        ticks = (now - start);    }    return (ticks);}

QueryPerformanceCounter is never called. Use QPC on Windows, and gettimeofday on POSIX, it isn't that hard to do it yourself. But beware of QPC!

##### Share on other sites
You have other issues to worry about on Windows systems as well, especially if your program is running on multicore systems. Basically what can happen is QPC can get its timing information from different cores between calls to the function, and the timing information between cores is not guaranteed to be in sync with each other. You essentially have to lock your timing code to one core in order to get reliable, monotonic timing information. At least, this is the case on Windows XP. I've heard this issue has been fixed in Vista, but I haven't checked myself.

I've heard the same issues can persist on Linux systems as well since, at least on x86 systems, gettimeofday() I believe relies on the TSC, which may or may not be synced across cores. Instead, you can use clock_gettime() with CLOCK_MONOTONIC as the clock ID, and you're guaranteed to get monotonic time then. clock_getres() can tell you what the resolution of the timer is, but from what I've heard it's on par with gettimeofday(). Again, I haven't done many tests myself, but I do remember looking into this pretty heavily not too long ago as I was trying to figure out how to get reliable high performance timing on multiple platforms.

##### Share on other sites
Yes, be careful of what romer is talking about. Pick a thread to run QPC on, and then use SetThreadAffinity to keep it on one core. Also make sure you have some code in place that will handle things gracefully in case you get a weird result that gives you a negative time delta (which can happen on some CPU's that use clock throttling).

##### Share on other sites
As hinted at above, there are all kinds of pitfalls which are described in an article/thread. I've posted source code [1.6 MB] of a library that goes to quite some trouble (1.5 KLOC) to choose a safe timer. It makes your app source-code compatible with Unix gettimeofday and clock_gettime by emulating those on Windows.
Patches and suggestions for improvement are most welcome.

## Create an account

Register a new account

• ## Partner Spotlight

• ### Forum Statistics

• Total Topics
627678
• Total Posts
2978605

• 12
• 12
• 10
• 12
• 22