9

Cpu Utilization Is Wrong

 3 years ago
source link: https://kernel.taobao.org/2017/12/CPU-Utilization-is-Wrong/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Dec 1, 2017

Cpu Utilization Is Wrong

http://www.brendangregg.com/blog/2017-05-09/cpu-utilization-is-wrong.html @木名 @雏雁

CPU Utilization is Wrong

CPU利用率我们并不陌生,但它却常常被人们误解。如果你认为它可以准确无误的刻画CPU的繁忙程度,那ä½ 就错了。那么什么是CPU利用率?请看下文分解。

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

File:naive.jpg

而实际的可能是:

File:real.jpg

“Stalled”表示处理器流水线停顿,一般由资源竞争、数据依赖等原因造成。多数情况下表现为等待访存操作,其中又以读操作为主。在停顿周期内,不能执行指令,这意味着你的程序不往前走。值得注意的是,图中stalled状态所占的比例是作者(Brendan Gregg)依据生产环境中的典型场景计算而来,具有普遍现实意义。因此,大多时候CPU处于stalled状态,而却被你忽略了。通过进一步分析CPU Stall的原因,可以指导代码优化,提高执行效率,这是我们深入理解CPU微架构的动力之一。

What really is CPU Utilization?

我们通常所说的CPU利用率是指”non-idle time”:即CPU不执行idle thread的时间。操作系统内核会在上下文切换时记录CPU的运行时间。当一个non-idle threadå¼始运行,100ms后结束,内核为认为这段时间内CPU利用率100%。这种度量方式源于分时复用系统。早在阿波罗登月舱的导航计算机中,idle thread当时被叫做“DUMMY JOB”,工程师通过“运行DUMMY JOB的时é´”和“运行实际任务的时间”来衡量导航系统的利用率。

So what’s wrong with this?

现在,CPU执行速度远远大于内存访问速度,等待访存的时间占了CPU时间的主要部分。当你在top中看到很高的%CPU,ä½ 可能认为处理器是瓶颈,但实际上却是内存。在很长一段时间内,CPU频率增长的速度大于DRAM访存延时降低的速度(CPU DRAM Gap)。到2005为止,处理器厂商才开始放弃“频率路线”,转向多核、超线程技术,再加上多处理器架构,这些都导致访存需求急剧上升。尽管厂商通过增大cache容量、优化cache策略、提升总线带宽来降低访存瓶颈,但我们的程序仍深受stall困扰。

what the CPUs are really doing?

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

# 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

	核心度量指标是IPC(instructions per cycle),它表示平均每个cpu cycle执行的指令数é。显然该值越大性能越好。上图中IPC为0.78,看起来还不错,是不是78% busy呢?现代处理器一般有多条流水线,运行perf的那台机器,IPC的理论值可达到4.0。如果我们从IPC的角度来看,CPU才以最高é度的19.5%(0.78 / 4.0)在运行。幸运的是,在处理器内部,有很多PMU event,可用来帮助我们分析造成stall的原因。用好PMU需要我们熟悉处理器微架构,可以参考Intel SDM。

	Best Practice

	如果 IPC < 1.0, å¾可能是memory stall占主导。可从软件和硬件两个方面考虑这个问题。软件方面:减少不必要的访存操作,提升cache命中率,尽量访问本地节点内存。硬件方面:增加cache容量,加快访存速度,提升æ»线带宽。 如果IPC > 1.0, 很可能是计算密集型的程序。可以试图减少执行指令的数量:消除不必要的工作。火焰图CPU flame graphs,非常适用于分析这类问题。硬件方面:尝试超频、使用更多的core或hyperthread。 作者根据PMU相关的工作经验,设定了1.0这个阈值,用于区分访存密集型(memory-bound)和计算密集型(cpu-bound)程序。读者可以根据自己的实际工作平台,合理调整这个阈值。

	What performance monitoring products should tell you

	性能工具中使用%CPU时都应该附带上IPC,或者将%CPU拆分为指令执行消耗cycle(%INS)和stalled的cycle(%STL)。 对应top,在Linux系统有一个能够显示每个处理器IPC的工具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

		    Other reasons CPU utilization is misleading

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

		    1. 温度原因导致处理器stall
		    2. Turboboost干扰了时钟速率
		    3. 内核使得时钟速率加快
		    4. 平均带来的问题:1分钟利用率平均80%,掩盖了中间100%部分
		    5. Spin Lock:CPU一直å¨被使用,同时IPC也很高,但是应用逻辑上并没有任何进展

		    Update: is CPU utilization actually wrong?

		    这个文章引起了大量留言(1,2,3),总结下我的回答是:这里讨论的并不是iowait(那是磁盘IO),而且如果你已经确认是访存密集型,是有些处理办法(参考上面)。

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

		    你可能会说利用率作为一个指标已经不对,Andrian Cockcroft之前讨论å·²经指出过。

		    结论

		    CPU利用率已经开始成为一个容易误导的指标:它包含访存导致的等待周期,这样会影响一些新应用。也许%CPU应该重命名为%CYC(cycles的缩写)。要清楚知道%CPU的含义,需要使ç¨其他指标进行辅助,其中就包括每周期指令数(IPC)。IPC < 1.0 多半意味着访存密集型,IPC > 1.0 多半意味着计算密集型。我在之前的文章中涵盖有IPC说明,以及用于测量IPC的Performance Monitoring Counters(PMCs)的介绍。

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

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK