CPU 利用率错误

我们都使用的 CPU 利用率指标具有严重的误导性,而且每年都在恶化。什么是 CPU 利用率?您的处理器有多忙?不,这不是它所衡量的。是的,我说的是每个人都使用的“% CPU ”指标。在每个性能监控产品中。在顶部(1)。
您可能认为 90% 的 CPU 利用率意味着:

它可能真正意味着什么:

停滞意味着处理器没有向前推进指令,通常是因为它正在等待内存 I/O。我在上面绘制的比率(忙碌和停滞之间)是我在生产中通常看到的。很有可能,你大多停滞不前,但不知道。
这对你意味着什么?了解您的 CPU 停滞了多少可以指导在减少代码或减少内存 I/O 之间进行性能调整工作。任何关注 CPU 性能的人,尤其是在基于 CPU 自动扩展的云上,都将从了解其 %CPU 的停滞组件中受益。
什么是 CPU 利用率?
我们称之为 CPU 利用率的指标实际上是“非空闲时间”:CPU 没有运行空闲线程的时间。您的操作系统内核(无论它是什么)通常会在上下文切换期间跟踪它。如果一个非空闲线程开始运行,然后在 100 毫秒后停止,内核认为 CPU 在整个时间内都在使用。
该指标与分时系统一样古老。阿波罗登月舱制导计算机(一种开创性的分时系统)将其空闲线程称为“DUMMY JOB”,工程师跟踪运行它的周期与实际任务作为重要的计算机利用率指标。(我之前写过这个。)
那么这有什么问题呢?
如今,CPU 已经变得比主内存快得多,而等待内存主导着仍然被称为“CPU 利用率”的东西。当您在 top(1) 中看到高 %CPU 时,您可能会认为处理器是瓶颈——散热器和风扇下方的 CPU 封装——而实际上是那些 DRAM 组。
这种情况变得越来越糟。 长期以来,处理器制造商在扩展其时钟速度方面的速度比 DRAM 扩展其访问延迟的速度更快(“CPU DRAM 差距”)。 这在 2005 年左右使用 3 GHz 处理器趋于平稳,从那时起,处理器已经使用更多内核和超线程以及多插槽配置进行扩展,所有这些都对内存子系统提出了更高的要求。 处理器制造商试图通过更大、更智能的 CPU 缓存以及更快的内存总线和互连来减少这种内存瓶颈。 但我们通常仍然停滞不前。
如何判断 CPU 真正在做什么
通过使用性能监控计数器 (PMC):可以使用 Linux perf 和其他工具读取的硬件计数器。 例如,测量整个系统 10 秒:

# perf stat -a -- sleep 10

 Performance counter stats for 'system wide':

     641398.723351      task-clock (msec)         #   64.116 CPUs utilized            (100.00%)
           379,651      context-switches          #    0.592 K/sec                    (100.00%)
            51,546      cpu-migrations            #    0.080 K/sec                    (100.00%)
        13,423,039      page-faults               #    0.021 M/sec                  
 1,433,972,173,374      cycles                    #    2.236 GHz                      (75.02%)
   <not supported>      stalled-cycles-frontend  
   <not supported>      stalled-cycles-backend   
 1,118,336,816,068      instructions              #    0.78  insns per cycle          (75.01%)
   249,644,142,804      branches                  #  389.218 M/sec                    (75.01%)
     7,791,449,769      branch-misses             #    3.12% of all branches          (75.01%)

      10.003794539 seconds time elapsed

这里的关键指标是每个周期的指令数(每个周期的 insns:IPC),它显示了我们在每个 CPU 时钟周期内平均完成了多少指令。越高越好(简化)。上面的 0.78 示例听起来不错(78% 忙?),直到您意识到该处理器的最高速度是 4.0 的 IPC。这也称为 4-wide,指的是指令获取/解码路径。这意味着,CPU 可以在每个时钟周期退出(完成)四条指令。因此,在 4 宽系统上的 IPC 为 0.78,意味着 CPU 以 19.5% 的最高速度运行。较新的英特尔处理器可能会迁移到 5 宽。
您可以使用数百个 PMC 来进一步挖掘:直接按不同类型测量停滞的周期。
在云端
如果您在虚拟环境中,您可能无法访问 PMC,具体取决于虚拟机管理程序是否支持来宾。我最近发布了关于 EC2 的 PMC:衡量 IPC,展示了 PMC 现在如何可用于基于 AWS EC2 Xen 的云上的专用主机类型。
解释和可操作的项目
如果您的 IPC < 1.0,您可能会出现内存停滞,软件调优策略包括减少内存 I/O、改善 CPU 缓存和内存局部性,尤其是在 NUMA 系统上。硬件调优包括使用具有更大 CPU 缓存和更快内存、总线和互连的处理器。
如果您的 IPC > 1.0,您可能会受到指令限制。寻找减少代码执行的方法:消除不必要的工作、缓存操作等。CPU 火焰图是这项调查的好工具。对于硬件调优,尝试更快的时钟频率和更多的内核/超线程。
对于我的上述规则,我在 1.0 的 IPC 上进行拆分。我从哪里得到的?根据我之前在 PMC 的工作,我弥补了这一点。以下是如何获得为您的系统和运行时自定义的值:编写两个虚拟工作负载,一个受 CPU 限制,一个受内存限制。测量他们的 IPC,然后计算他们的中点。
哪些性能监控产品应该告诉你
每个性能工具都应该显示 IPC 和 %CPU。或者将 %CPU 分解为指令退休周期与停滞周期,例如 %INS 和 %STL。
至于top(1),Linux有tiptop(1),按进程显示IPC:

tiptop -                  [root]
Tasks:  96 total,   3 displayed                               screen  0: default

  PID [ %CPU] %SYS    P   Mcycle   Minstr   IPC  %MISS  %BMIS  %BUS COMMAND
 3897   35.3  28.5    4   274.06   178.23  0.65   0.06   0.00   0.0 java
 1319+   5.5   2.6    6    87.32   125.55  1.44   0.34   0.26   0.0 nm-applet
  900    0.9   0.0    6    25.91    55.55  2.14   0.12   0.21   0.0 dbus-daemo

CPU 利用率具有误导性的其他原因
导致 CPU 利用率误导的不仅仅是内存停滞周期。 其他因素包括:

温度跳闸使处理器停止工作。
Turboboost 改变时钟频率。
内核随速度步长改变时钟速率。
平均值的问题:1 分钟内使用了 80%,隐藏了 100% 的爆发。
自旋锁:CPU 被占用,IPC 很高,但应用程序没有进行逻辑上的前进。
更新:CPU 利用率实际上是错误的吗?
这篇文章有数百条评论,这里(下)和其他地方(1、2)。感谢大家花时间和对这个话题的兴趣。总结一下我的回答:我根本不是在谈论 iowait(那是磁盘 I/O),如果您知道自己受内存限制,还有一些可操作的项目(见上文)。
但是 CPU 利用率真的是错误的,还是只是严重误导?我认为很多人将高 %CPU 解释为处理单元是瓶颈,这是错误的(正如我之前所说)。那时你还不知道,它通常是外部的。该指标在技术上是否正确?如果 CPU 停顿周期不能被其他任何东西使用,那么它们是否因此被“利用等待”(这听起来像是矛盾的说法)?在某些情况下,是的,您可以说 %CPU 作为操作系统级别的指标在技术上是正确的,但具有严重的误导性。但是,对于超线程,那些停滞的周期现在可以被另一个线程使用,因此 %CPU 可以将实际上可用的周期计算为已使用的周期。那是错误的。在这篇文章中,我想专注于解释问题和建议的解决方案,但是,是的,
正如 Adrian Cockcroft之前所讨论的,您可能会说利用率作为一个指标已经被打破了。
结论
CPU 利用率已成为一个极具误导性的指标:它包括在主内存上等待的周期,这可能会主导现代工作负载。也许 %CPU 应该重命名为 %CYC,是周期的缩写。您可以通过使用其他指标(包括每周期指令数 (IPC))来弄清楚 %CPU 的真正含义。IPC < 1.0 可能意味着内存受限,而 IPC > 1.0 可能意味着指令受限。我在上一篇文章中介绍了 IPC,包括对测量它所需的性能监控计数器 (PMC) 的介绍。
显示 %CPU 的性能监控产品(即所有这些产品)也应该显示 PMC 指标来解释这意味着什么,而不是误导最终用户。例如,它们可以显示 %CPU 与 IPC,和/或指令退休周期与停滞周期。有了这些指标,开发人员和运营商可以选择如何更好地调整他们的应用程序和系统。

转载翻译自: https://www.brendangregg.com