Assembly timers

Started by
9 comments, last by GameDev.net 18 years, 9 months ago
Timers seems to be a big thing lately. I'm really just looking for an accurate timer ms or higher that works, no jumps, lags etc. Most provided methods just aren't good enough and you have to go ahead and program your own timer. However, I've read queryPerformanceCounter() is not very accurate, but most articles I read end up using it. I'm guessing it fixes the jumps, etc on the time it's getting from QPC? I was thinking maybe a good way would be using assembly as it probably has a way to get the system time quickly and accurately. Does anyone know this?
Advertisement
The real problem is not what language you are using but the limits of the timer hardware used in PC's.

Unless you have special high-precision/high-resolution timer hardware in you computer, QueryPerformanceCounter or the Windows multimedia timers is AFAIK pretty much as good as you are going to get. Just stay away from the normal windows timers or trying to time using Sleep. (under Windows that is, I know nothing about timing under Linux/Unix)

I don't believe writing your own timers in assembly will give you very much. It probably will cut down timer latency slightly, but I doubt it's worth the extra work.

(Though I'm not a guru on these issues, so I might have missed something)
Ah I see I want as good a timer as possible, but I guess the best I'm gonna get isn't going to be perfectly accurate. I don't wanna have the best timer as it'd be hard to make and like you said not the extra work, but I just want as good a timer as most games out there.
I remember reading about how QueryPerformanceCounter() can adjust itself to use the RDTSC assembly instruction if the system has an Intel chip. So, if that's the case, there is no way you can implement a more accurate timer. Your dissambler will tell you if, in fact, that instruction is being called.
Check out the Zen Timer from Michael Abrash.

Its reprinted in Michael Abrash's Graphics Programming Black Book (Special Edition).

You might be able to google the implementation...

It is an timer implementation in assembly, but might not work [well] for windows.
cloakwww.theblackroom.ca
Quote:Original post by Ganoosh_
Most provided methods just aren't good enough and you have to go ahead and program your own timer. However, I've read queryPerformanceCounter() is not very accurate,


What system have you observed QueryPerformanceCounter being inaccurate on?

As far as I'm aware, on normal PC hardware, QPC is nice and smooth, and accurate to a lot more than 1ms (maybe 1us or better - more than enough)

Perhaps you're looking at an antique version of Windows, or an embedded platform. If so, your mileage may vary.

I'm talking about current (i.e. Windows 2000 + ) versions of Windows on desktop hardware.

Mark
Check out
http://developer.intel.com/drg/pentiumII/appnotes/RDTSCPM1.HTM
or
http://www.math.uwaterloo.ca/~jamuir/rdtscpm1.pdf

Cycle exact timming so your resolution is only limited by the speed of your CPU...not a problem really since the maximum resolution on a 500Mhz CPU is 2E-09s. A 1GHz is obviously 1E-09s and 2GHz is 5E-10s. More than enough.

The article is interesting as well with examples on how to get accurate timming/cycle counts which are invariant to the cache.

It doesn't take much to setup a quick wrapper for the asm...failing that QueryPerformanceCounter() is adequate considering it is for a game.
The first link doesn't work, it gives a page not found error. However the second is very useful thanks a lot, but how can I get the processor frequency? That's obviously going to change across systems, so I can't just hard code a number.
The problem with rdtsc is that it is only accurate in a single processor architecture with a very simple processor. Modern desktop processors and just about all laptop processors will adjust their clock speed dynamically, so you have no way of knowing how long a clock cycle lasts. In multiprocessor architectures, it is easy for the timers on each processor to get out of sync and then if your program is moved from one cpu to another then suddenly the count will vary wildly, and that could happen every single frame under certain conditions.

If query performance counter uses rdtsc, then it will also have the above problems, even if you use query performance frequency because you still have no idea how long each individual time unit is, only how long a time unit RIGHT NOW would be.

The most accurate timer I'm aware of is timeBeginPeriod, timeGetTime, timeEndPeriod.

I'm fairly certain there are more accurate timers in the hardware, but I'm not sure there is a standard way to access them. It is possible that QueryPerformanceCounter will use such timers if it detects that rdtsc isn't reliable, but I've heard of people having problems that would only happen if QPC used rdtsc when it shouldn't.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
QueryPerformanceCounter is really only for getting very high resolution profile info under tightly controlled conditions.

Perhaps when it was originally created it was useful for general timing but technology has marched on. Nowadays when processors change their frequency every other cycle you need to use a real timer that actually measures *time* and not cycles.
-Mike

This topic is closed to new replies.

Advertisement