Generally timeGetTime() is best for timing game logic - GetTickCount isn't quite high enough resolution, and QPC & RDTSC are a lot more trouble than they are worth for that purpose.
For profiling on the other hand, either RDTSC or QPC can be quite worthwhile. I prefer RDTSC over QPC, though microsoft recommends QPC.
The four common time functions I use on win32:
GetTickCount() returns the current time in milliseconds relative to some arbitrary zero (usually, though not always system boot time), as a 32 bit integer (so it wraps every 49 days or so). It is usually the fastest method to measure a time. Unfortunately it is low resolution - typically it only updates 64 times per second. Contrary to popular rumor, calling timeBeginPeriod(1) will not increase its resolution on any system I've tested that on. There is also a 64 bit variant if you're worried about it wrapping.
timeGetTime() returns the current time in milliseconds relative to some arbitrary zero, as a 32 bit value (so it wraps after 49 days or so). It's not as fast as GetTickCount, but still pretty reasonable. It can be accurate to a single millisecond, though that may require calling timeBeginPeriod(1) first. Using timeGetTime requires linking against winmm.lib and including Mmsystem.h.
QueryPerformanceCounter() returns the current time in arbitrary units as a 64 bit integer. You can figure out what the units are by calling QueryPerformanceFrequency(), and the units will not change (absent a reboot). The underlying implementation of this varies widely, and each implementation has its own quirks and bugs that may occur on some hardware, making this obnoxious to use in widely deployed applications. Some implementations are very slow, others are reasonable, though none are as fast as GetTickCount or even timeGetTime. Typically timing resolution is better than 1 microsecond, though not necessarily much better.
RDTSC is an x86 / x64 assembly language opcode that returns the current time in units of CPU cycles (ie as a 64 bit integer. On some compilers it can be accessed as an intrinsic (__rdstc), on others you'll need inline asm. Its speed varies a bit between CPUs but is usually pretty reasonable - typically significantly faster than QueryPerformanceCounter but not as fast as GetTickCount. Unfortunately it has a few quirks - not as many as QueryPerformanceCounter, but still a lot more than the lower resolution time functions. It can sometimes run backwards on multicore CPUs when you switch cores due to imperfect synchronization between cores, the units are difficult to figure out, and the units can change in mid-timing due to power management changing the rate of the CPU clock.
Note that each of these four methods can drift relative to the other three - there is no clear authoritative flow of time.
Sleep(100)
in your code. It has nothing to do with the timers. – Apr 04 '12 at 13:28QueryPerformanceCounter
. As user3535668 has already stated it has issues. This is true even on more or less modern hardware. E.g. I have seen it misbehave on Intel Sandy Bridge systems as well as AMD Trinity systems (both running Windows 7). All of which I would consider more or less "current". And by misbehave I mean: it will jump and stall by/for multiple milliseconds at a time. So much that it's not suitable for stable, jerk-free frame timing.timeGetTime
on the other hand is much more reliable. – Paul Groke May 23 '15 at 00:01static
. Why make themstatic
? – swdev Jun 11 '16 at 19:26