Cross-Platform High-Performance timing?
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.
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.
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.
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!
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.
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.
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).
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.
Patches and suggestions for improvement are most welcome.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement