开发者

How do I use less CPU with loops?

I've got a loop tha开发者_Go百科t looks like this:


while (elapsedTime < refreshRate) 
{
    timer.stopTimer();
    elapsedTime=timer.getElapsedTime();
}
I read something similar to this elsewhere (C Main Loop without 100% cpu), but this loop is running a high resolution timer that must be accurate. So how am I supposed to not take up 100% CPU while still keeping it high resolution?


You shouldn't busy-wait but rather have the OS tell you when the time has passed.

http://msdn.microsoft.com/en-us/library/ms712704(VS.85).aspx

High resolution timers (Higher than 10 ms)

http://msdn.microsoft.com/en-us/magazine/cc163996.aspx


When you say that your timer must be "accurate", how accurate do you actually need to be? If you only need to be accurate to the nearest millisecond, then you can add a half-millisecond sleep inside the loop. You can also add a dynamically-changing sleep statement based off of how much time you have left to sleep. Think of something like (pseudocode):

int time_left = refreshRate - elapsedTime;
while (time_left > 0) {
    if (time_left > threshhold)
        sleep_for_interval(time_left / 2);
    update_timestamp(elapsedTime);
    time_left = refreshRate - elapsedTime;
}

With that algorithm, your code will sleep for short bursts if it detects that you still have a while to wait. You would want to run some tests to find an optimal value for threshhold that balances CPU usage savings for risk of overshoot (caused by your app losing the CPU when it sleeps and not getting any more CPU time in time).

The other method for high-resolution timing is to use a hardware timer that triggers an periodic interrupt. Your interrupt handler would send a signal to some thread that it needs to wake up and do something, after which it goes back to sleep and waits for the next signal to come in.

Real-Time Operating Systems have ways to do this sort of things built into the OS. If you're doing Windows programming and need extremely precise timing, be aware that that's not the sort of thing that a general-purpose OS like Windows handles very well.


Look at some timers delivered by the OS, like POSIX usleep.
On the other hand, if you need hyper precision, your code will not work either, because the OS will break this loop after it would exhaust its process time quantum and jump to the kernel space to make some system tasks. To this end you would need some special OS with interruptable kernel and tools delivered by it; look for RTOS keyword.


Typically, you yield to the OS in some fashion. This allows the OS to take a break from your program and do something else.

Obviously this is OS dependent, but:

#ifdef _WIN32
    #include <windows.h>
#else
    #include <unistd.h>
#endif

void yield(void)
{
    #ifdef _WIN32
        Sleep(0);
    #else
        usleep(1);
    #endif
}

Insert a call to yield before you stop the timer. The OS will report less time usage by your program.

Keep in mind, of course, this makes your timer "less accurate", because it might not update as frequently as possible. But you really shouldn't depend on extreme-accuracy, it's far too difficult. Approximations are okay.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜