简体   繁体   English

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

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

I've got a loop that 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. C Main Loop没有100%cpu ),但是这个循环正在运行一个必须准确的高分辨率计时器。 So how am I supposed to not take up 100% CPU while still keeping it high resolution? 那么我怎么能在保持高分辨率的同时不占用100%的CPU呢?

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 http://msdn.microsoft.com/en-us/library/ms712704(VS.85).aspx

High resolution timers (Higher than 10 ms) 高分辨率计时器(高于10毫秒)

http://msdn.microsoft.com/en-us/magazine/cc163996.aspx 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). 您可能希望运行一些测试以找到threshhold的最佳值,以平衡CPU使用率节省的过冲风险(由于您的应用程序在睡眠时丢失CPU并且没有及时获得CPU时间)。

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. 如果您正在进行Windows编程并且需要非常精确的计时,请注意,像Windows这样的通用操作系统处理得非常好。

Look at some timers delivered by the OS, like POSIX usleep . 查看操作系统提供的一些计时器,如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. 寻找RTOS关键字。

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. 在停止计时器之前插入对yield的调用。 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. 近似没问题。

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

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