如何在循环中使用更少的 CPU?
我有一个看起来像这样的循环:
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?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. So how am I supposed to not take up 100% CPU while still keeping it high resolution?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您不应该忙着等待,而应该让操作系统告诉您时间已经过去。
http://msdn.microsoft.com/en-us /library/ms712704(VS.85).aspx
高分辨率计时器(高于 10 毫秒)
http://msdn.microsoft.com/en-us/magazine/cc163996.aspx
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
当您说您的计时器必须“准确”时,您实际上需要多准确?如果您只需要精确到最接近的毫秒,那么您可以在循环内添加半毫秒的睡眠。您还可以根据您剩余的睡眠时间添加动态变化的睡眠语句。想一想(伪代码):
使用该算法,如果您的代码检测到您还有一段时间等待,它将短暂休眠。您可能需要运行一些测试来找到
threshhold
的最佳值,以平衡 CPU 使用节省与超调风险(由于您的应用在休眠时失去 CPU 并且无法及时获得更多 CPU 时间) )。高分辨率定时的另一种方法是使用触发周期性中断的硬件定时器。您的中断处理程序会向某个线程发送一个信号,表明它需要唤醒并执行某些操作,之后它会返回睡眠状态并等待下一个信号进入。
实时操作系统有方法可以执行此类操作内置于操作系统中。如果您正在进行 Windows 编程并且需要极其精确的计时,请注意,像 Windows 这样的通用操作系统不能很好地处理这种情况。
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):
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.
查看操作系统提供的一些计时器,例如 POSIX
usleep
。另一方面,如果您需要超精度,您的代码也将无法工作,因为操作系统在耗尽其处理时间量并跳转到内核空间以执行某些系统任务后将打破此循环。为此,您需要一些具有可中断内核的特殊操作系统及其提供的工具;寻找 RTOS 关键字。
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.
通常,您会以某种方式屈服于操作系统。这允许操作系统从您的程序中休息一下并执行其他操作。
显然,这是依赖于操作系统的,但是:
在停止计时器之前插入对yield的调用。操作系统将报告您的程序使用的时间较少。
当然,请记住,这会使您的计时器“不太准确”,因为它可能不会尽可能频繁地更新。但你真的不应该依赖极端的准确性,这太困难了。近似值是可以的。
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:
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.