如何在循环中使用更少的CPU?

时间:2010-07-19 22:47:06

标签: c++ windows visual-studio infinite-loop

我有一个看起来像这样的循环:


while (elapsedTime < refreshRate) 
{
    timer.stopTimer();
    elapsedTime=timer.getElapsedTime();
}
我在其他地方读过类似的东西( C Main Loop without 100% cpu),但是这个循环运行的是一个必须准确的高分辨率计时器。那么我怎么能在保持高分辨率的同时不占用100%的CPU?

4 个答案:

答案 0 :(得分:6)

你不应该忙 - 等一下,而是让操作系统告诉你什么时候过去了。

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

高分辨率计时器(高于10毫秒)

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

答案 1 :(得分:4)

当您说您的计时器必须“准确”时,您实际需要的准确度如何?如果您只需要精确到最接近的毫秒,那么您可以在循环内添加半毫秒的睡眠。您还可以根据您剩余的睡眠时间添加动态变化的睡眠声明。想想(伪代码):

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;
}

使用该算法,如果您的代码检测到您仍有一段时间等待,则会短暂停留。您可能希望运行一些测试以找到threshhold的最佳值,以平衡CPU使用率节省的过冲风险(由于您的应用程序在睡眠时丢失CPU并且没有及时获得CPU时间而导致)。 / p>

高分辨率定时的另一种方法是使用触发周期性中断的硬件定时器。你的中断处理程序会向某个需要唤醒并执行某些操作的线程发送一个信号,之后它会重新进入休眠状态并等待下一个信号进入。

实时操作系统有办法在操作系统中内置这类内容。如果您正在进行Windows编程并且需要非常精确的计时,请注意,像Windows这样的通用操作系统处理得非常好。

答案 2 :(得分:3)

查看操作系统提供的一些计时器,如POSIX usleep 另一方面,如果你需要超精度,你的代码也不会工作,因为操作系统会在耗尽其进程时间量并跳转到内核空间以完成一些系统任务之后打破这个循环。为此,您需要一些特殊的操作系统,其中包含可中断的内核和工具;寻找RTOS关键字。

答案 3 :(得分:2)

通常,您会以某种方式屈服于操作系统。这允许操作系统从您的程序中休息并执行其他操作。

显然这是依赖操作系统的,但是:

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

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

在停止计时器之前插入一个对yield的调用。操作系统将报告您的程序使用时间减少。

请记住,当然,这会使您的计时器“不太准确”,因为它可能不会尽可能频繁地更新。但你真的不应该依赖极端准确性,这太难了。近似值没问题。

相关问题