繁体   English   中英

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

[英]How do I use less CPU with loops?

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


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

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

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

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

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

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

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时间)。

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

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

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

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

显然这取决于操作系统,但是:

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM