CPU 利用率背后的真相,99% 人都搞错了...


来源:内核月谈
http://www.brendangregg.com/b...html

导读:本文翻译自 Brendan Gregg 去年的一篇博客文章 “CPU Utilization is Wrong”,从标题就能想到这篇文章将会引发争议。

文章一上来就说,咱们“人人皆用、到处使用,每一个性能监控工具里都在用”的 top 命令里的 “%CPU” 指标,是不对的,其并不是用于衡量 CPU 的繁忙程度的正确指标,做者谴责了一下众人(或许也包括你我)的这一行为是具备很大的误导性(deeply misleading)的,并且这种状况还在连年恶化。对于这么大一顶帽子,让咱们暂且按下躁动的心,听听做者是怎么深刻阐释他的观点的。segmentfault

1. 引言

可能你认为的 90% CPU 利用率意味着这样的情形:架构

而实际却多是这样的:less

CPU 并不是 90% 的时间都在忙着,很大一部分时间在等待,或者说“停顿(Stalled)”了。这种状况表示处理器流水线停顿,通常由资源竞争、数据依赖等缘由形成。多数状况下表现为等待访存操做,其中又以读操做为主。在停顿周期内,不能执行指令,这意味着你的程序不往前走。工具

值得注意的是,图中 “Stalled” 状态所占的比例是做者依据生产环境中的典型场景计算而来,具备广泛现实意义。所以,大多时候 CPU 处于停顿状态,而你殊不知道,由于 CPU 利用率这个指标没有告诉你真相。经过进一步分析 CPU 停顿的缘由,能够指导代码优化,提升执行效率,这是咱们深刻理解CPU微架构的动力之一。性能

2. CPU 利用率的真实含义是什么?

咱们一般所说的CPU利用率是指 “non-idle time”:即CPU不执行 idle thread 的时间。操做系统内核会在上下文切换时记录CPU的运行时间。优化

假设一个 non-idle thread 开始运行,100ms 后结束,内核会认为这段时间内 CPU 利用率为 100%。这种度量方式源于分时复用系统。早在阿波罗登月舱的导航计算机中,idle thread 当时被叫作 “DUMMY JOB”,工程师经过比对运行 “DUMMY JOB” 和 “实际任务” 的时间来衡量导航系统的利用率。spa

那么这个所谓“利用率”的问题在哪儿呢?操作系统

当今时代,CPU 执行速度远远大于内存访问速度,等待访存的时间成为占用 CPU 时间的主要部分。当你在 top 中看到很高的 “%CPU”,你可能认为处理器是瓶颈,但实际上倒是内存。线程

在过去很长一段时间内,CPU 频率增加的速度大于 DRAM 访存延时下降的速度(CPU DRAM gap),直到2005年先后,处理器厂商们才开始放弃“频率路线”,转向多核、超线程技术,再加上多处理器架构,这些都致使访存需求急剧上升。尽管厂商经过增大 cache 容量、优化 cache 策略、提高总线带宽来试图缓解访存瓶颈,但咱们的程序仍深受 CPU stall 困扰。

3. 如何真正辨别 CPU 在作些什么?

在 PMC(Performance Monitoring Counters) 的帮助下,咱们能看到更多的 CPU 运行状态信息。下图中,perf 采集了10秒内所有 CPU 的运行状态。

这里咱们重点关注的核心度量指标是 IPC(instructions per cycle),它表示平均每一个 CPU cycle 执行的指令数量,很显然该数值越大性能越好。上图中IPC 为 0.78,看起来还不错,是否是 78% busy 呢?现代处理器通常有多条流水线,运行 perf 的那台机器,IPC 的理论值可达到 4.0。

若是咱们从 IPC的角度来看,这台机器只运行到其处理器最高速度的 19.5%(0.78 / 4.0)。幸运的是,在处理器内部,有不少 PMU event,可用来帮助咱们分析形成 CPU stall 的缘由。用好 PMU 须要咱们熟悉处理器微架构,能够参考 Intel SDM。

4. 最佳实践是什么?

若是 IPC < 1.0, 极可能是 Memory stall 占主导,可从软件和硬件两个方面考虑这个问题。软件方面:减小没必要要的访存操做,提高 cache 命中率,尽可能访问本地节点内存;硬件方面:增长 cache 容量,加快访存速度,提高总线带宽。

若是IPC > 1.0, 极可能是计算密集型的程序。能够试图减小执行指令的数量:消除没必要要的工做。火焰图CPU flame graphs,很是适用于分析这类问题。硬件方面:尝试超频、使用更多的 core 或 hyperthread。做者根据PMU相关的工做经验,设定了1.0这个阈值,用于区分访存密集型(memory-bound)和计算密集型(cpu-bound)程序。读者能够根据本身的实际工做平台,合理调整这个阈值。

5. 性能工具应该告诉咱们什么?

做者认为,性能工具中使用 %CPU 时都应该附带上 IPC,或者将 %CPU 拆分为指令执行消耗 cycle(%INS) 和 stalled 的 cycle(%STL)。对应到 top,在 Linux 系统有一个可以显示每一个处理器 IPC 的工具 tiptop:

6. 其余可能让 CPU 利用率引发误解的因素

除了访存致使的 stall 容易让人误解 CPU 利用率外,还有其余一些因素:

  • 温度缘由致使处理器 stall;
  • Turboboost 干扰了时钟速率;
  • 内核使得时钟速率加快;
  • 平均带来的问题:1分钟利用率平均 80%,掩盖了中间 100% 部分;
  • 自旋锁: CPU 一直在被使用,同时 IPC 也很高,可是应用逻辑上并无任何进展。

7. 更新:CPU 利用率真的错了吗?

这篇文章引发了大量留言:

总结下做者的回答是:这里讨论的并非 iowait (那是磁盘IO),并且若是你已经确认是访存密集型,是有些处理办法(参考上面)。

那么 CPU 利用率指标是确确实实错误的,仍是只是容易误导?如做者前面所说,他认为许多人把高 CPU 利用率理解为瓶颈在 CPU 上,这一行为才是错误的;

其实单看 CPU 利用率并不清楚瓶颈在何处,不少时候瓶颈是在外部。这个指标技术上看是否正确?若是 CPU stall 的周期并不能被其余地方使用,它们是否是也就所以是“忙于等待“(听起来有点矛盾)?在有些状况,确实如此,你能够说 CPU 利用率做为操做系统级别的指标技术上看是对的,可是容易产生误导。

从另外一个角度来讲,有超线程的状况下,那些 stalled 的周期是能够被其余线程使用的,这时 “%CPU” 可能会将可用的周期统计为正在使用,这种状况是错误的。这篇文章做者想关注的是解释清楚这个问题,并给出解决方法建议,但没错,CPU 利用率这个指标自己也是存在一些问题的。

当你可能会说利用率做为一个指标已经不对,Andrian Cockcroft以前讨论已经指出过 (http://www.hpts.ws/papers/200..._HPTS-Useless.pdf )。

8. 结论

CPU 利用率已经开始成为一个容易误导的指标:它包含访存致使的等待周期,这样会影响一些新应用。也许 “%CPU” 应该重命名为 “%CYC”(cycles的缩写)。

要清楚知道 “%CPU” 的含义,须要使用其余指标进行辅助,其中就包括每周期指令数(IPC)。IPC < 1.0 多半意味着访存密集型,IPC > 1.0 多半意味着计算密集型。做者以前的文章中涵盖有 IPC 说明,以及用于测量 IPC 的 Performance Monitoring Counters(PMCs)的介绍。

全部的性能监控产品若是展现 “%CPU”,都应该同时展现 PMC 指标用于解释其真实意义,不要误导用户。好比,能够把 “%CPU” 和 “IPC” 一块儿放,或者说指令执行消耗周期和 stalled 周期。有这些指标以后,开发者和操做者就可以知道该如何更好地对应用和系统进行调优。

若有错误或其它问题,欢迎小伙伴留言评论、指正。若有帮助,欢迎点赞+转发分享。

欢迎你们关注民工哥的公众号:民工哥技术之路
image.png

相关文章
相关标签/搜索