0

编辑:

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

顺便说一句,面对更大、更重要的问题,我肯定会确保将微优化保持在最低限度!

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

出于某种原因,我的程序(我为欢笑和练习而制作的控制台闹钟)占用大量 CPU 资源。它消耗大约 2mB 的 RAM,对于这样一个小程序来说已经相当多,但它有时会以超过 50% 的资源破坏我的 CPU。

大多数时候我的程序除了倒计时什么都不做,所以我想我的程序的这部分是对我的 CPU 造成如此大压力的部分,尽管我不知道为什么。如果是这样,您能否推荐一种减少它的方法或者如果问题不能轻易解决,也许可以使用一个库来代替?

/* 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"),我知道使用它真的非常慢而且不是一个好主意。我将更改那个 post-haste,但是,因为它每 60 秒才激活一次,并且有一个明显的滞后峰值,我知道大多数时候这不是问题。

第二个功能也仅每六十秒用更新的剩余时间重写屏幕内容。

如果很明显这个函数不是问题,我将在调用 wait、clearScreen 和 display 的函数中进行编辑。我已经尝试引用大多数变量,因此它们不会被复制,并避免endl因为我听说它与\n.

4

6 回答 6

15

这:

while( clock() < endwait ) {} 

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

这样做的正确方法是丢弃整个wait函数,而只是使用:

sleep(seconds);

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

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

于 2010-04-26T22:29:37.600 回答
6

这称为忙等待。whileCPU 在循环中全速旋转它的轮子。sleep您应该使用对or的简单调用来替换 while 循环usleep

我不知道 2 MB,尤其是对整个程序一无所知,但这真的不是什么值得强调的事情。出于效率原因,可能是 C 运行时库在启动时吸收了那么多。

于 2010-04-26T22:26:53.530 回答
3

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

运行并检查一个只包含

int main() { for (;;) }

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

于 2010-04-26T22:36:03.953 回答
2

您在这里旋转而没有屈服,因此消耗 CPU 周期也就不足为奇了。

放下一个

  Sleep(50);

在while循环中。

于 2010-04-26T22:29:08.393 回答
2

每当您的while线程获得执行时间片时,循环就会使处理器保持忙碌状态。如果您只想等待一段确定的时间,则不需要循环。您可以通过一次调用来替换它sleepusleep或者nanosleep(取决于平台和粒度)。他们暂停线程执行,直到您指定的时间量过去。

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

如果您想了解此问题的确切原因,请阅读调度

于 2010-04-26T22:31:56.647 回答
1

而(时钟()<结束等待){睡眠(0);} // 让给同等优先级的线程

于 2010-04-26T22:32:30.700 回答