cpu 性能_weixin_30455661的博客-程序员秘密

技术标签: java  运维  操作系统  

我们平时使用的CPU利用率方法是极具误导性的,并且一年更甚一年。那么什么是CPU利用率?是你的CPU到底有多忙,是像“% CPU”这样到处在用的指标所显示的那样吗?

在top命令里,你看到90%的CPU利用率是这样:

然而它真正想表达的是这个意思:

Stall(这里译作“怠速”)是说这个处理器没有在跑指令,比如在等待内存I/O的时候。我上图所画的比例(“忙”与“怠速”之间)是我在真实生产环境中遇到的,并且你的CPU也很可能是处于“怠速”状态。

 

这些对你有什么意义呢?理解CPU怠速多少,会直接影响到你在减少代码或者减少内存I/O的调优工作。

 

那么真正的CPU利用率怎么算呢?

平时的CPU利用都是非空闲时间,即CPU不运行idle线程(比如Windows里的空闲进程)的时间。你的操作系统那会平时会在上下文切换的时候跟踪它,但是假如一个非idle线程开始运行100毫秒后停止,那内核会认为后面这段时间CPU也在这个非idle线程上。

 

在老旧的分时系统里,这么算没毛病。阿波罗登月舱的导航系统计算机将这里的idle线程叫做“DUMMY JOB”,工程师用利用它来测算计算机的利用率,可以参考之前我写过的这样一篇文章(链接地址:http://www.brendangregg.com/usemethod.html#Apollo)。

 

那么它有什么毛病呢?

现在的CPU比内存已经快了很多倍,但等待内存的时间仍然被算进CPU时间中。当你在top命令中看到较高的“%CPU”的时候,你可能认为它到达了一个性能瓶颈,就是散热片和风扇下面的那个CPU,但实际上,这是那一根根内存条的锅。

 

如何分辨CPU到底在忙啥?

使用性能监测计数器(PMC)——一种能够用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

 

这里的一个关键指标就是instructions per cylce(IPC,每CPU周期执行指令数),它能够显示每CPU周期内每个CPU运行了多少指令,越高说明效率越高。上述示例中,这一值为0.78,但这并不说明CPU利用率为78%,因为现代CPU的IPC最大值为4.0(新的已经到了5.0),也就是4-wide。CPU在执行指令时,单个指令会被分割为多个步骤,比如取指令、解码、执行、内存访问、写寄存器等,这些命令如果在单个CPU周期内最多执行一个,那么需要5个CPU周期来完成一条命令,IPC就是0.2,如果采用指令流水线,即3~5-wide的CPU,那么完美状态下1个CPU周期就可以完成一条命令,IPC就是1。(译者注:作者文中使用了CPU clock cycle表示通常所说的CPU周期,为了避免与晶振时钟周期混肴我并没有将其译为CPU时钟周期。)

 

当然,还有数百个其他你可以用来测量的性能计数器。

如果在虚拟化环境中,guest一般不能直接访问PMC,这取决于hypervisor是否支持。我最近写的一篇The PMCsof EC2: Measuring(链接地址:http://www.brendangregg.com/blog/2017-05-04/the-pmcs-of-ec2.html) IPC展示了AWS EC2中基于Xen的虚拟机如何使用PMC。

 

最佳实践

如果你的IPC小于1.0,你可能遇到了内存操作密集型,软件调优策略可以有减少内存I/O,增强内存本地访问性,尤其是在NUMA系統上。硬件调优策略则是使用CPU cache较大以及更快的内存、总线和内联技术。

 

如果你的IPC > 1.0,你可能是指令密集型。可以试图减少指令的执行数量,比如消除不必要的工作和缓存操作等,可以用一下CPU火焰图(链接地址:http://www.brendangregg.com/FlameGraphs/cpuflamegraphs.html)。硬件调优方面,可以尝试高主频、多核、超线程的CPU。

 

性能检测产品应该告诉你什么呢?

性能检测工具都应该显示出每个进程的IPC,或者是按照指令周期与怠速周期,比如%INS和%STL,下图为Linux中的tiptop命令:

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利用率具有误导性的其他理由

 

  1. 使得这个%CPU指标错误的理由除了CPU在内存的怠速周期外,还有如下因素:

  2. 温度也能使CPU进入怠速;

  3. Turboboost(睿频)引起时钟频率变化;

  4. SpeedStep引起时钟频率变化;

  5. 一分钟内的80%的平均利用率并不能表示100%的突发利用率(类似网络QoS);

  6. 自旋锁:CPU在很严肃地瞎忙;

 

Update: CPU利用率真的错了吗?


自这篇文章发布以后,留言讨论非常激烈,已经有了上百条了。首先谢谢你们对这话题感兴趣并花时间阅读,但我在这里还是要统一回复:我对disk的iowait并不关心(译者注:PC CPU不能直接操作外部存储),并且文中也已经给出了内存操作密集型的对应调优措施。

 

然而,CPU利用率到底是从本质上错了还是仅仅是有误导性了?我认为需要人将高CPU利用率视为处理单元的瓶颈的事儿,是错的。那么这个指标的计算方法从技术上讲正确吗?如果CPU在怠速期间不能被其他任何进程使用,那么这不就是所谓的“使用等待”(听起来有点矛盾)。某些情况下,%CPU作为一个操作系统层面的指标是技术正确但是容易误导人的。在超线程中,怠速周期可以被其他线程使用,所以%CPU的算法也会将其算在内,而实际上并没有利用。那样是不对的,这篇文章中我强调的是解释问题并提出对策,并且,这个指标也有技术上的问题。

结论

CPU利用率已成为一个极具误导性的指标:它算进了等待主存的周期,而这类周期在现代的CPU负载中占据不少。如果使用额外指标,你就能搞清楚%CPU到底意味着什么,包括每CPU周期执行指令数(IPC)。IPC < 1.0可能意味着你的应用是内存密集型,而IPC > 1.0则可能是指令密集型。我在之前的一篇文章,显示%CPU的性能监控产品也应该显示PMC测量指标,并给予充分解释,这样才不会误导用户。比如,它们可以一起显示%CPU和IPC,或者指令周期与怠速周期。有了这些指标,开发或管理人员才能在应用和操作系统中选择正确的调优方式。

 

译者的话

本文翻译自Brendan Gregg的博客文章《CPU Utilization is Wrong》,原文链接为http://www.brendangregg.com/blog/2017-05-09/cpu-utilization-is-wrong.html,就是那本《性能之巅(中译)》的作者,调试工具dtrace的作者,现就职于NetFlix。

 

PS:为什么要翻译这个文章呢?因为很多时候总感觉PC的这个CPU利用率的百分比显示没能真实反应我的CPU到底忙不忙,在学校的时候用单片机也是算idle,但到了PC后隐约感觉这么算不对,看了BG的文章后才恍然大悟。另外这篇文章之前已经被翻译过,但作者又有更新,也挺有意思的,我就重新翻了一遍,并加了一些弹幕。

转载于:https://www.cnblogs.com/jkred369/p/7153606.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30455661/article/details/98998600

智能推荐

Axure RP使用攻略--带遮罩层的弹出框(9)_汐若雨的博客-程序员秘密_axure点击弹出浮层

实现目标:1、&nbsp;&nbsp; 点击按钮弹出带遮罩层的对话框;2、&nbsp;&nbsp; 页面上下左右滚动时,弹出的对话框水平和垂直始终居中。实现步骤如下:1、 拖入编辑区2个矩形,并点右键—转换—转换为动态面板;2、 双击其中一个动态面板设置标签为“遮罩层”(看个人喜好随便命名),并双击状态1进入编辑;3、 点击状态1里面的矩形,设置大小与网站页面大小相同,以便完全遮盖;然后,设置矩形边框为“无”;最后设置填充色的透明度为50%(看个人喜好),并选择填充色为灰色(看个人喜好);.

cocos2dx之创建Button_漫步者、的博客-程序员秘密_cocos2dx 创建button

利用CCControlButton创建一个Button,代码如下:void MyBottonBastLayer::initLayer() { CCSize size = CCDirector::sharedDirector()->getWinSize(); CCScale9Sprite *psc9Selected = CCScale9Sprite::create("btn-ab

根据经纬度实现附近的人_YOUR_HERO_的博客-程序员秘密

根据经纬度实现附近的人本文依旧是一篇杂记,如果对你有帮助的话,基本是一些思想类,简单架构类的方式1.使用一些经纬度的计算方式2.使用goeHash达到我们的mysql、oracle、plsql之类树状的数据库无法完成的部分3.可以使用一些特殊类型的类库进行计算,比如一些MongoDB,之类三维立体数据库 4.结合redis缓存开启附近人模式的人的地理位置,然后将这人的key设置为地...

交换机的三种端口类型及转发原理_Listen_Silently的博客-程序员秘密_交换机端口类型

一 端口类型1 Access用户模式2 Trunk链路模式3 Hybrid模式(跟Trunk很类似但比trunk高级)二 端口介绍2.1 Access类型端口:只允许默认vlan的以太网帧,也就是说只能属于一个vlan,Access端口在收到以太网帧后打上vlan标签,转发时在剥离vlan标签,一般情况下一端连接的是计算机。

EF6 增删改查_cooledi的博客-程序员秘密_ef6 增删改查

private DbContext _dbContext; public DbContext CurrentContext { get { if (_dbContext == null) { _dbCo

移动端卡片拖动切换效果_css3和js适合移动mobile的弹性堆叠图片切换特效_weixin_39925413的博客-程序员秘密

这是一款效果非常酷的js和CSS3适合移动mobile的弹性堆叠图片切换特效。该弹性堆叠图片切换特效的特点是支持移动触摸屏设备,可以通过手指滑动来切换图片。所有图片开始时堆叠在一起,当你用手指滑动图片的时候,堆叠图片就像弹簧被扯动一样,最上面的一张图片被拉到最下面,效果非常炫酷。使用方法HTML结构该弹性堆叠图片切换特效的HTML结构使用的嵌套结构。rutrum tellus a tempus :...

随便推点

android studio容易出现的问题_fjnu_se的博客-程序员秘密

**android studio容易出现的问题**​作为一名android studio的初学者,使用android studio的时候出现了诸多问题,最终多方面查询相关资料后得以解决,其中几个主要的问题。一、sdk路径的问题,因为是很久之前的问题了,没有保留出现问题时的截图,但是解决方法还记得。首先先试试重启电脑,有时候就是加载出错导致的,重启有时候就能解决问题,原本能运行的,有时候就会不能运行。我在尝试多种方法无法修复的时候最终发现只是我加载出错了,重启就可以了,但是在过程中了解了许多处

[CPU+目标检测] openvino实现Robomaster自瞄_三丰杂货铺的博客-程序员秘密_robomaster自动瞄准

这篇文章为大连理工大学Robomaster凌Bug战队的李乐恒同学成果!他在CPU上利用openvino这样的深度学习算法实现了Robomaster的自瞄,大大提高了robomaster自瞄的上界,且达到了良好的检测效果。所有代码全部开源, github主页如下:https://github.com/Len-Li/openvino-robomaster文章目录0.introduction1.1 使用的模型库1.2 数据集1.3 训练+评测1.3.1 安装TensorFlow Object Detec

接口隔离原则详解--七大面向对象设计原则(4)_Geek.Fan的博客-程序员秘密

接口隔离原则的来源:  类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对于类A和类B来说不是最小接口,则类B和类D必须去实现他们不需要的方法。因为使用多个专门的接口比使用单一的总接口要好,所以便提出了接口隔离原则。接口隔离原则的目的:  将臃肿的接口I拆分为独立的几个接口,类A和类C分别与他们需要的接口建立依赖关系。也就是采用接口隔离原则。接口隔离原则的两种定义

判断用户是否关注公众号_8316AND8317的博客-程序员秘密_判断是否关注公众号

背景:客户端和公众号均绑定在【同一个微信开放平台】,客户端使用微信登陆现在有一个新需求:客户端有一个奖励,关注公众号之后才能领取奖励。客户端直接跳转到微信,用户搜索公众号名称搜索关注。实现逻辑:同一个微信开放平台下,微信用户的unionid是唯一的,用户在登陆客户端app和公众号时,openid是不一样的。用户关注公众号之后,获取unionid,然后查找uniond一样的...

android 添加js对象吗,Android和JS的交互_与漁的博客-程序员秘密

现在很多App为了降低开发成本和维护成本,都会内置Web网页,在安卓端是通过WebView来实现的,这就要求我们开发人员具备Android和JS交互的开发能力。我将通过这篇文章来记录我的学习历程,在学习过程中我还是通过一个demo来加深理解,下面先贴上效果图:安卓与js的交互效果图分别展示了js调用安卓方法的三种效果以及安卓调用js方法的两种效果,下面我把这五个方法拆开来单个学习理解。一、先介绍一...

PAT乙级题1010 一元多项式求导 (25分)几个坑点(主要是第三个测试点)_ZoeEot的博客-程序员秘密

本人新人,这些代码都慢慢摸索出来的,在博客上没看到正解,也可能是我没找到,就是第三个测试点的新手版=-=;;代码如下#include&lt;stdio.h&gt;int main(){ int k,n; int i=0; while(scanf("%d%d",&amp;k,&amp;n)!=EOF){ if(n==0&amp;&amp;k==0){ if(i!=0) prin...

推荐文章

热门文章

相关标签