我们都使用的 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