QueryPerformanceCounter() without polling

Started by
12 comments, last by Anon Mike 16 years, 11 months ago
Quote:Original post by andy82Call a function every <ms> milliseconds with the utmost precision that Windows can offer me and without blocking window event handling.

How precise does it have to be? Windows is not a realtime OS, so there are certain limitations on how precise you can get.

Quote:
@Admiral:
This is somewhat off-topic, but if Sleep() is not very precise how would you put the application to sleep without using the Sleep() function? Of course, I don't want to poll QPC() until the time has elapsed because that eats 100% percent of the CPU.

I'd do without the precision. Sleep() is not very precise because there is no way it can be. When your app is not actively executing, it has to await its turn. But if you want to be precise, you need to make sure your app is running all the time, which means you have to have 100% CPU usage.
And even then, you aren't sure to get any kind of precision.
Windows decides all on its own which app to run when, and it regularly halts your app in order to run all the other apps for a bit. During that time, you won't be able to handle Windows messages, and you won't be able to query timers because... your app isn't running.
Nothing you can do about that, short of giving your app realtime priority, which is a bad idea for about 200 reasons, and still won't make the problem go away entirely.

That's why I asked how much precision you need. You might be able to get millisecond precision *most* of the time, at least if there aren't too many apps running, and while your app is actively executing, QPC can give you microsecond precision. But only while you're executing. If you're yielding the CPU to let other apps run (or if Windows just decides to interrupt you), you have to wait until Windows feels like resuming your app. And there's nothing you can do about that.

Btw, Sleep(0) might be useful to you. That doesn't actually put your app in a sleep queue, so you won't miss out on anything much, but simply turns the CPU over to Windows, ending your current timeslice.
Advertisement
This is either a "real-time" application or it's a typical windows application which doesn't do anything until it gets input.

If it's real time then take 100% of the CPU who cares? You're not actually using 100%, task manager may say so but you're not. Other applications will run perfectly fine unless you're on a PII-350 or something and using XP...

If this is a regular windows application like a web browser then I don't see why you need a game style main loop. But since you've given us basically no information it's difficult to help you.

You've also not told us what sort of accuracies you need in a timer. Nanosecond? Millisecond?

"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin

I think there are about three possibilities here, and none of them are really an ideal solution:

1. Don't worry about yielding CPU usage and just keep polling away until enough time has passed.
Advantage: Highest accuracy possible.
Disadvantage: Uses 100% CPU.

2. Use sleep(0) to yield to threads of equal or higher priority.
Advantage: Gives programs of equal or higher priority more opportunities to get time slices while you're waiting for enough time to pass, while still polling at a very high rate.
Disadvantage: Still uses 100% CPU (I think) and lower priority tasks still aren't given a chance to run during your sleep(0).

3. Use sleep(1) to sleep for the lowest resolution timeslice.
Advantage: Reduces CPU usage
Disadvantage: Less accurate control of the timing, it may be more difficult or impossible to maintain a steady framerate. It could be that the next frame was supposed to be started much earlier than the amount of time you will sleep for, especially if the game processing does require a significant amount of time. Similiar to waiting for WM_TIMER messages.
Another alternative is to use MsgWaitForMultipleObjects instead of Sleep. Then you can have a standard message dispatch loop that is able to timeout when it's time for the next frame.
-Mike

This topic is closed to new replies.

Advertisement