【问题标题】:How come adding even a tiny delay during polling reduces CPU usage?为什么在轮询期间添加一个微小的延迟会降低 CPU 使用率?
【发布时间】:2018-10-04 17:32:07
【问题描述】:

我需要创建需要轮询硬件设备的软件。

static void Main(string[] args)
{
    while(true)
    {
        DoSomething();
        Task.Delay(1).Wait();
    }
}

static void DoSomething(){}

我注意到,如果我不添加最小的延迟,那么 CPU 使用率会达到 30-40%,但即使延迟 1 毫秒,使用率也会保持在百分之几左右。

我的开发环境是.net/c#。

对于我和企业来说,没有必要增加 1 毫秒的延迟,但它似乎让世界变得不一样了。

感觉即使添加一点延迟也是一个好主意。为什么?

编辑

鉴于上面的那段代码,DoSomething() 为空,为什么添加 Task.Delay(1).Wait(); 会大大降低 CPU 使用率? 感觉是一件很琐碎的事情。怎么会有这么大的影响?

【问题讨论】:

  • 这不是一个微小的延迟。就处理器而言,1ms 是一个很长的时间。 DoSomething() 是做什么的?如果需要 1 毫秒,CPU 使用率将减少 50%
  • 当您没有任何延迟时,您的 DoSomething 方法将被尽快调用,而您的 CPU 正在为其工作而无需任何休息。但是,当您添加 1 毫秒延迟时,CPU 会从您的方法中休息 1 毫秒(10 000 个 cpu 滴答声)。
  • 顺便说一句,1 毫秒的延迟更像是 15.6 毫秒,这是 Windows 上计时器的默认分辨率。即使你指定 1ms,延迟也至少是 15.6
  • 如果您不添加延迟,您只需在循环中执行 DoSomething()。当您添加延迟时,会创建一个延续,并且循环的执行会暂停一段时间。请注意,周期不是 1 毫秒,因为 Windows 上计时器的分辨率不是那么小。默认分辨率为 15.6 毫秒(定时器中断每秒 64 次)。
  • 您真正希望多久轮询一次每台设备?什么设备?例如,有些不能那么快地轮询。如果您确实需要快速轮询,则可以更改系统的计时器分辨率,但会增加功耗。 Chrome 因这样做而臭名昭著。另一方面,视频、音频等多媒体服务需要更快的计时器使用特殊服务和 API 来工作。

标签: c# polling


【解决方案1】:

假设DoSomething 接受0.1 ms。然后,没有延迟,它每秒执行10_000 次。由于延迟,它每秒执行的次数少于900 次。如 cmets 中所述,实际延迟取决于操作系统,可能为 15.6 ms,因此实际上每秒可能有 ~60 调用。

因此 CPU 必须完成的工作量差异很大。

【讨论】:

    【解决方案2】:

    像这样写

    while (true)
    {
        DoSomething();   
    }
    

    您实际上是在告诉编译器构建一个可以翻译成人类语言的代码,如下所示:

    亲爱的 CPU,请尽快DoSomething()

    这就是为什么当你添加一个微小的延迟时 CPU 负载下降的解释。因为那样的话,代码会被翻译成这样的:

    亲爱的CPU,请DoSomething(),然后你就可以休息数百万个周期了。之后,再次执行DoSomething()

    请注意,对于在 2-4 GHz 频率下工作的 CPU 来说,1 ms 已经很长了。

    【讨论】:

      猜你喜欢
      • 2023-04-03
      • 1970-01-01
      • 2023-03-27
      • 2012-03-05
      • 1970-01-01
      • 1970-01-01
      • 2020-12-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多