震惊,用了这么多年的 CPU 利用率,其实是错的

2018年12月22日 08:43:09 Linuxer_ 阅读数:50

https://blog.csdn.net/juS3Ve/article/details/85219620

来源:内核月谈

原文链接:

http://www.brendangregg.com/blog/2017-05-09/cpu-utilization-is-wrong.html

本文中若有任何疏漏错误,责任在于编译者。有任何建议和意见,请回复内核月谈微信公众号,或通过 caspar at linux.alibaba.com 反馈。

导读:本文翻译自 Brendan Gregg 去年的一片博客文章 “CPU Utilization is Wrong”,从标题就能想到这篇文章将会引起争议。文章一上来就说,我们“人人皆用、处处使用,每个性能监控工具里都在用”的 top 命令里的 “%CPU” 指标,是不对的,其并非用于衡量 CPU 的繁忙程度的正确指标,作者谴责了一下众人(或许也包括你我)的这一行为是具有很大的误导性(deeply misleading)的,而且这种情况还在连年恶化。对于这么大一顶帽子,让我们暂且按下躁动的心,听听作者是怎么深入阐释他的观点的。

1. 引言

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

而实际却可能是这样的:

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” 和 “实际任务” 的时间来衡量导航系统的利用率。

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

当今时代,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 利用率外,还有其他一些因素:

  1. 温度原因导致处理器 stall;

  2. Turboboost 干扰了时钟速率;

  3. 内核使得时钟速率加快;

  4. 平均带来的问题:1分钟利用率平均 80%,掩盖了中间 100% 部分;

  5. 自旋锁: CPU 一直在被使用,同时 IPC 也很高,但是应用逻辑上并没有任何进展。

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

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

  • http://www.brendangregg.com/blog/2017-05-09/cpu-utilization-is-wrong.html 的留言栏;

  • https://news.ycombinator.com/item?id=14301739

  • https://www.reddit.com/r/programming/comments/6a6v8g/cpu_utilization_is_wrong/

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

那么 CPU 利用率指标是确确实实错误的,还是只是容易误导?如作者前面所说,他认为许多人把高 CPU 利用率理解为瓶颈在 CPU 上,这一行为才是错误的;其实单看 CPU 利用率并不清楚瓶颈在何处,很多时候瓶颈是在外部。这个指标技术上看是否正确?如果 CPU stall 的周期并不能被其他地方使用,它们是不是也就因此是“忙于等待“(听起来有点矛盾)?在有些情况,确实如此,你可以说 CPU 利用率作为操作系统级别的指标技术上看是对的,但是容易产生误导。从另一个角度来说,有超线程的情况下,那些 stalled 的周期是可以被其他线程使用的,这时 “%CPU” 可能会将可用的周期统计为正在使用,这种情况是错误的。这篇文章作者想关注的是解释清楚这个问题,并给出解决方法建议,但没错,CPU 利用率这个指标本身也是存在一些问题的。

当你可能会说利用率作为一个指标已经不对,Andrian Cockcroft之前讨论已经指出过 (http://www.hpts.ws/papers/2007/Cockcroft_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 周期。有这些指标之后,开发者和操作者就能够知道该如何更好地对应用和系统进行调优。


"Linux阅码场"是专业的Linux及系统软件技术交流社区,企业和Linux人才的连接枢纽。

[转帖]震惊,用了这么多年的 CPU 利用率,其实是错的的更多相关文章

  1. 震惊,用了这么多年的 CPU 利用率,其实是错的

    导读:本文翻译自 Brendan Gregg 去年的一片博客文章 "CPU Utilization is Wrong",从标题就能想到这篇文章将会引起争议.文章一上来就说,我们&q ...

  2. CPU利用率异常的分析思路和方法交流探讨

    CPU利用率异常的分析思路和方法交流探讨在生产运行当中,经常会遇到CPU利用率异常或者不符合预期的情况,此时,往往暗示着系统性能问题.那么究竟是核心应用的问题?是监控工具的问题?还是系统.硬件.网络层 ...

  3. python多进程提高cpu利用率

    cpu参数: 1个物理cpu,2个逻辑cpu(超线程),单核 具体 http://blog.csdn.net/dba_waterbin/article/details/8644626   物理CPU. ...

  4. cpu利用率和cpu 队列

    SIP的第四期结束了,因为控制策略的丰富,早先的的压力测试结果已经无法反映在高并发和高压力下SIP的运行状况,因此需要重新作压力测试.跟在测试人员后面做了快一周的压力测试,压力测试的报告也正式出炉,本 ...

  5. 查看进程,按内存从大到小 ,查看进程,按CPU利用率从大到小排序

    查看进程,按内存从大到小 ps -e -o "%C : %p : %z : %a"|sort -k5 -nr 查看进程,按CPU利用率从大到小排序 ps -e -o "% ...

  6. 使用Java编写一个简单的Web的监控系统cpu利用率,cpu温度,总内存大小

    原文:http://www.jb51.net/article/75002.htm 这篇文章主要介绍了使用Java编写一个简单的Web的监控系统的例子,并且将重要信息转为XML通过网页前端显示,非常之实 ...

  7. HighChartS cpu利用率动态图(Java版)

    来源:http://www.cnblogs.com/haifg/p/3217699.html   最近项目需要监控服务器cpu的利用率,并做成动态图.在网上查找了一些资料,最终选择了HighChart ...

  8. Linux如何统计进程的CPU利用率

    1.0 概述 在Linux的/proc文件系统,可以看到自启动时候开始,所有CPU消耗的时间片:对于个进程,也可以看到进程消耗的时间片.这是一个累计值,可以"非阻塞"的输出.获得一 ...

  9. 如何提高多线程程序的cpu利用率

    正如大家所知道的那样,多核多cpu越来越普遍了,而且编写多线程程序也是件很简单的事情.在Windows下面,调用CreateThread函数一次就能够以你想要的函数地址新建一个子线程运行.然后,事情确 ...

随机推荐

  1. Maven——settings.xml配置

    settings.xml配置 原文 <?xml version="1.0" encoding="UTF-8"?> <!-- Licensed ...

  2. Why do Kafka consumers connect to zookeeper, and producers get metadata from brokers?

    Why do Kafka consumers connect to zookeeper, and producers get metadata from brokers? Ask Question u ...

  3. [Java] SpringMVC工作原理之三:ViewResolver

    一.ViewResolver 根据视图的名称将其解析为 View 类型的视图,如通过 ModelAndView 中的视图名称将其解析成 View,View 是用来渲染页面的,也就是将 Model 填入 ...

  4. 弱省胡策 Magic

    弱省胡策 Magic 求\(n\)个点\(n\)的条边的简单联通图的个数. 毒瘤,还要写高精. 我们枚举环的大小\(k\),\(\displaystyle ans=\sum_{k=3}^nC_n^k ...

  5. 如何生成git ssh key

    公司有自己的git版本控制,自己注册账号后,管理员同意,就可以查看项目代码了,但是要克隆的话需要在本地生成git ssh key 一.进入.ssh文件夹. cd ~/.ssh 若没有.ssh文件夹,则 ...

  6. 解决 双显卡 y7000笔记本 (Dual Graphics) Ubuntu 18.04 GDM3 无法外接显示器

    sudo gedit /lib/systemd/system/gdm3.service 把其中的 ExecStartPre=/usr/share/gdm/generate-config 更改为 Exe ...

  7. spring boot 注解方式 idea报could not autowire

    File-Project Structure 页面 Facets下删掉 Spring(直接右键Delete) 这个解答是对的.并不会降低安全性!!因为创建项目的时候,都是先创建空项目再创建web mo ...

  8. 深度学习框架PyTorch一书的学习-第三章-Tensor和autograd-2-autograd

    参考https://github.com/chenyuntc/pytorch-book/tree/v1.0 希望大家直接到上面的网址去查看代码,下面是本人的笔记 torch.autograd就是为了方 ...

  9. reedis 解决在windows下启动闪退

    windows下安装https://github.com/MicrosoftArchive/redis/releases第一次启动报错: [2368] 21 Apr 02:57:05.611 # Cr ...

  10. MyBatis动态SQL(认真看看, 以后写SQL就爽多了)

    目录 0 一起来学习 mybatis 1 数据准备 2 if 标签 2.1 在 WHERE 条件中使用 if 标签 2.1.1 查询条件 2.1.2 动态 SQL 2.1.3 测试 2.2 在 UPD ...