极其CPU密集型闹钟

时间:2010-04-26 22:23:19

标签: c++ cpu clock

编辑:

我想感谢大家的快速回复^^ Sleep()按预期工作,我的CPU不再被这个程序恶意吞噬了!我将按原样保留这个问题,但是让每个人都知道CPU问题已经得到了方便和专业的回答:D

除此之外,我肯定会确保在面对更大,更重要的问题时将微优化保持在最低限度!

=============================================== =================================

出于某种原因,我的节目,一个我笑的笑声和练习的控制台闹钟,非常占用CPU。它消耗大约2mB的RAM,这对于这么小的程序来说已经相当多了,但它有时会破坏我的CPU超过50%的资源。

大部分时间我的程序除了倒数秒之外什么都不做,所以我想我的程序的这一部分是导致CPU压力太大的部分,尽管我不知道为什么。如果是这样的话,你能否推荐一种方法让它 less ,或者如果问题不能轻易解决,可能会使用一个库?

/* The wait function waits exactly one second before returning to the *
 * called function.                                                   */     
 void wait( const int &seconds )
 {
 clock_t endwait; // Type needed to compare with clock()
 endwait = clock() + ( seconds * CLOCKS_PER_SEC ); 

 while( clock() < endwait ) {} // Nothing need be done here.
 }

如果有人浏览CPlusPlus.com,这是他们编写的clock()函数的正版复制/粘贴,作为clock()的示例。很多为什么评论//Nothing need be done here如此黯淡无光。我还不完全确定clock()到底是什么。

程序的其余部分调用另外两个仅每六十秒激活一次的函数,否则返回调用者并倒计时另一秒,所以我不认为CPU太密集 - 虽然我不知道,这是我第一次尝试优化代码。

第一个功能是使用system("cls")清除控制台,我知道,它确实非常非常慢,并不是一个好主意。我将改变后匆忙,但是,因为它只是每60秒激活一次,并且有明显的滞后尖峰,我知道这不是大多数时候的问题。

第二个功能仅使用更新的剩余时间每60秒重写一次屏幕内容。

我将在调用wait,clearScreen的函数中进行编辑,如果显示此函数不是问题则显示。我已经尝试引用大多数变量,因此不会复制它们,并且避免使用endl,因为我听说它与\n相比有点慢。

6 个答案:

答案 0 :(得分:15)

此:

while( clock() < endwait ) {} 

不是“无所事事”。当然内部 while循环没有做任何事情,但clock() < endwait的测试不是免费的。事实上,它正在一次又一次地执行,就像你的系统可以处理它一样快,这正在推动你的负载(可能是50%,因为你有一个双核处理器,这是一个单线程程序只能使用一个核心。)

执行此操作的正确方法是删除整个wait函数,而只是使用:

sleep(seconds);

实际上会阻止程序执行指定的秒数,并且在执行此操作时不会占用任何处理器时间。

根据您的平台,您需要包含<unistd.h>(UNIX和Linux)或<windows.h>(Windows)才能访问此功能。

答案 1 :(得分:6)

这称为忙碌等待。 CPU在while循环中以全油门旋转车轮。您应该通过简单调用sleepusleep替换while循环。

我不知道2 MB,特别是对整个程序一无所知,但这真的不是要强调的东西。可能是因为效率原因,C运行时库在启动时会吸收很多。

答案 2 :(得分:3)

CPU问题得到了很好的解决。至于内存问题,目前尚不清楚2 MB实际测量的是什么。它可能是映射到应用程序地址空间的所有库的总大小。

运行并检查只包含

的程序
int main() { for (;;) }

衡量平台上的基线内存使用情况。

答案 3 :(得分:2)

你在这里没有屈服,所以燃烧CPU周期就不足为奇了。

放弃

  Sleep(50);

在while循环中。

答案 4 :(得分:2)

只要您的线程获得执行时间片,while循环就会使处理器保持忙碌状态。如果你想要的是等待一段确定的时间,你就不需要循环了。您可以通过拨打sleepusleepnanosleep(取决于平台和粒度)来替换它。它们暂停执行线程,直到您指定的时间过去为止。

或者,您可以放弃(yield)剩余的时间片,调用Sleep(0)(Windows)或sched_yield()(Unix / Linux /等)。

如果您想了解此问题的确切原因,请参阅scheduling

答案 5 :(得分:1)

while(clock()&lt; endwait){Sleep(0); } //屈服于相同优先级的线程