为什么空循环使用如此多的处理器时间?

pau*_*aul 13 c c++

如果我的代码中有一个空的while循环,例如:

while(true);
Run Code Online (Sandbox Code Playgroud)

它将使处理器使用率提高约25%.但是,如果我执行以下操作:

while(true)
    Sleep(1);
Run Code Online (Sandbox Code Playgroud)

它只会使用大约1%.

那为什么呢?

更新:感谢所有伟大的回复,但我想我真的应该问这个问题,睡眠()背后的算法是什么?这更像是我想知道的.

Jos*_*dan 36

对于前者,true必须由处理器检查条件,因为应用程序可能会获得焦点.一旦应用程序获得处理器注意,它true就像任何其他循环条件一样检查是否可以执行循环中的下一条指令.当然,循环中的下一条指令也是true.基本上,您正在强制处理器不断地确定是否true为真,这虽然是微不足道的,但执行时会不断地使处理器陷入困境.

在后者中,处理器检查true一次,然后执行下一个语句.在这种情况下,这是1ms等待.由于1 ms远远大于检查所需的时间true,并且处理器知道它可以在此等待期间执行其他操作,因此您可以释放大量电量.

  • 编译器通常会将`while(true){}`优化为无条件跳转到同一条指令,如`jmp $`.在这种情况下,不需要检查`true`,它只是一个不断执行的跳转指令. (11认同)
  • @Artelius - 它仍然无条件地每秒跳跃数十亿次.当你添加一个`sleep`语句时,处理器会在很短的时间内跳转,然后长时间休眠.至于为什么它是25%的@CKret,那纯粹依赖于架构.如果不知道OP有哪种处理器(以及有多少),就没有办法说出原因. (2认同)

Jam*_*ack 20

我猜你的多核处理器上有四个内核,这可以解释25%,因为你完全占用了一个处理繁忙循环的处理器,因为唯一的突破就是当应用程序被延迟时另一个应用程序可以运行(但可能不会发生,具体取决于负载).

当你让一个线程进入休眠状态时,它允许操作系统执行其他操作,并且它知道何时至少返回并唤醒线程,这样它就可以继续它的工作.

  • 拥有多个CPU核心的隐藏优势 - 它可以保护您免受编写错误的代码!认真! (8认同)
  • 四个多核?这些多核中有多少个核心?:P (4认同)

Sco*_*lle 7

第一个连续使用CPU操作.后者切换当前运行的线程的上下文,put处于睡眠模式,从而允许调度其他进程.


Art*_*ius 7

你有一台四核机器,对吗?如果是这样,

while(true);
Run Code Online (Sandbox Code Playgroud)

实际上是使用100%的核心.

对于操作系统来说,您的程序似乎还有很多工作要做.因此,操作系统让程序继续这项工作.它无法区分你的程序编号像疯了一样碾压和做无用的无限循环.

Sleep(1);
Run Code Online (Sandbox Code Playgroud)

另一方面明确地告诉操作系统你在下一毫秒内没有工作要做.因此操作系统将停止运行您的程序并让其他程序运行.


Yan*_*ton 7

空循环实际上不是空的.一个循环本身至少是一个比较和跳回到比较.现代CPU每秒可以执行数百万次这样的操作.

第二个循环中的sleep语句放弃对操作系统的控制至少1毫秒.在此状态下,应用程序将被有效停止,并且不会继续处理.停止x个时间量的结果减少了比较次数,因此cpu可以每秒执行的cpu时钟周期的百分比.

关于25%,支持超线程或多核处理器的英特尔处理器可能会污染性能统计数据.空循环有效地顶住至少一个处理器核心.

在多核CPU不存在的那一天,用户确实需要多处理/任务.有几种方法可以实现同时运行多个进程的错觉.

一种方法是以这样一种方式设计应用程序,即他们需要经常放弃对系统的控制,以便让其他进程运行一段时间.在旧的Windows版本中就是这种情况.如果给定的应用程序设计糟糕,以至于它没有放弃控制,或者陷入无限循环,那么整个PC都会被冻结.

毋庸置疑,这不是最好的方式,它被先发制人的多任务处理所取代.这里指示可编程中断定时器以给定间隔中断正在运行的进程,以执行一些调度程序代码,使其他进程可以运行.

  • 对于挑剔很抱歉,但是空循环*是*空的,因为这个表达式引用了正文,而不是循环代码本身. (3认同)
  • 我只是想指出,空循环确实需要处理,即使它没有主体。对于刚接触编程的人来说,这可能是违反直觉的。 (2认同)

Dro*_*per 0

因为你让处理器忙于一遍又一遍地评估循环。

使用睡眠实际上可以让其他线程在 CPU 上执行,并且伴随着非常短的上下文切换,看起来好像 CPU 暂时空闲了一段时间。