CPU性能分析工具原理
很多软件都要做性能分析和性能优化。很多语言都会有他的性能分析工具,例如如果优化C++的性能,我们可以用Visual Studio自带的性能探测器,或者使用Intel VTune Profiler。了解性能分析工具的原理有助于了解工具给出的数据与结果,也能帮助我们在遇到异常结果时排查哪里出了问题。这篇博客简单总结一下常见的性能分析工具原理。
性能分析器原理分类
性能分析工具大部分都可以分为下面几类
- 基于采样(Sampling)
- 基于插装(Instrumentation)
- 基于事件(Event-based)
1. 基于采样
基于采样的分析器会每隔一个固定时间间隔暂停所有线程的执行,然后分析有哪些线程正在执行,那些线程处于就绪状态。对于这类线程,我们记录每个线程的调用堆栈,以及其他需要的信息。我们称这个行为为一次采样,记录下来的每个堆栈为一个样本。然后在结束性能分析的时候我们统计记录下载的堆栈,看每个堆栈被记录了多少次,或者每个函数被记录了多少次。统计学告诉我们,那些执行时间比较长的函数、堆栈,被记录的次数会更多。如果堆栈A被记录了200次,堆栈B被记录了100次,那么堆栈B的执行时间是堆栈A的2倍。我们可以计算某个堆栈样本的数量占总样本数的比例,这个比例就是堆栈执行时间的占比。用Visual Studio的性能探测器我们看到的百分比和数字就是值样本的占比(也就是时间占比)和样本次数。
很多性能分析工具都是基于采样的方式。运行性能分析器是会影响被测程序的性能的,而基于采样的有点是对性能影响比较小,不需要重新编译程序,非常方便。
2.基于插装
插装是指通过修改程序,往里面加入性能分析相关代码,来收集、监控相关性能指标。例如我们可以在一个函数的开头写下计数代码,我们就可以知道在运行中这个函数被执行了多少次。一般来说基于插装的性能分析更为准确,但是对性能影响比较大。因为需要修改代码,所以也不是很方便。另外,基于插装的分析也可能会引起海森堡bug(heisenbug)。海森堡bug是指当你再运行程序的时候能遇到这个bug,但是试图定位这个bug时却遇不到这个bug。这个bug往往是因为在定位bug时修改了软件的运行环境/流程,导致软件执行和生产时不一样,于是就遇不到这个bug了。这个命名的来源很有意思,海森堡是量子力学的著名科学家,他提出了不确定性原理,以及观察者理论。这个理论认为,观察会影响例子的状态,导致观察粒子和不观察粒子会导致不同的结果,这个和海森堡bug的情形非常相似。关于观察者理论,有兴趣的人可以再了解一下。
回到正题,基于插装也可以再进行划分:
- 人手修改源码:这个是我们非常常用的性能分析方法。我们做性能分析有时候就会直接修改源码,计算某一段代码的执行时长,或者计算函数调用次数,分析哪段代码耗时。
- 工具自动修改源码
- 工具自动修改汇编/中间码
- 运行时注入
- ......
3.基于事件
在软件执行过程中,可能会抛出某些事件。我们通过统计事件出现的次数,事件出现的时机,可以得到软件的某些性能指标。事件又可以分为软件事件和硬件事件。软件事件比如Java可以在class-load的时候抛出事件。硬件事件则是使用专门的性能分析硬件。现在很多CPU里面都有用于分析性能的性能监控单元(PMU),PMU本身是一个寄存器,在某个事件发生时寄存器里面的值会+1。例如我们可以设置为当运行中发生memory cache miss的时候PMU寄存器+1,这样我们就知道一段时间内发生了多少次memory cache miss。性能分析器使用PMU时,会给PMU设置需要统计的事件类型,以及Sample After Value (SAV)。SAV是指寄存器达到什么值之后出发硬件中断。例如,我们可以给PMU设置SAV为2000,统计事件为memory cache miss。那么当cache miss发生2000次时,发生硬件中断。这个时候性能分析器就可以收集CPU的IP,调用堆栈,进程ID等等信息,分析器结束时进行统计分析。
基于硬件事件的优点是,对被测程序的影响非常小,比基于采样还小,可以使用更短的时间间隔收集信息,而且可以收集CPU的非常重要的性能指标,例如cache miss,分支预测错误,等等。
但是基于硬件事件的分析器也有它的一些问题,导致数据上的误差:
- SAV一般会设置成很大的数值:
像是Intel VTune Profiler一般会把SAV设置成10,000到2,000,000,发生中断时我们能知道最后一次触发该事件是哪段代码引起的,但是在这之前的9,999到1,999,999次事件我们是不知道的。他会认为所有10,000到2,000,000次事件都是由同一处代码引起的。如果发生了很多次中断,收集了很多次信息,而某一行代码出现了很多次,那么根据统计学,我们能知道这行代码触发了多少次事件。但是如果某一行代码只出现了一两次,那么我们很难知道这行代码到底出发了多少次时间。 - CPU一个核只有几个PMU,但是可以统计的事件有几十种:
一个PMU可以统计一个事件,但是我们分析一个软件可能需要统计几十种事件。一般的处理方法是多路复用(Multiplexing)。比如说前10ms记录事件A,后10ms记录事件B,再后10ms由记录事件A,……,这样轮流记录事件A和事件B,那么一个PMU就可以同时统计两个事件。多路复用可以解决少量PMU统计大量事件的问题,但是也会导致每种事件记录的样本数减少,倒是最后统计计算的结果误差更大。 - Intel® Hyper-Threading Technology导致记录不准:
Hyper-Threading技术可以让一个CPU物理核变成两个逻辑核,但是这两个逻辑核会共享很多硬件,包括PMU。这会出现什么问题呢?例如我们有两个线程再两个CPU核同时运行。我们觉得实在两个核上执行,但是实际上是在同一个物理核上。所以PMU会同时统计两个程序触发的事件,我们很难区分到底是哪个逻辑核出发了多少事件,所以PMU记录的数据就会不准确。另外,性能分析器计算性能指标时会使用一些硬件参数,Hyper-Threading技术会让这些参数不准确。例如一般个CPU核能再一个clock执行4个uop,所以CPI(Cycle Per Instruction,每个clock执行的指令数)是0.25。但是如果使用了Hyper-Threading技术,实际的CPI会是0.5 - Event Skid(事件打滑)会导致记录的IP不准确:
PMU记录有些事件会出现一定延时,所以在执行分析器的中断处理代码时,可能被测程序已经又执行了好多指令,IP已经向后滑动了很远了。一般如果我们只是统计函数的话不会太大问题,但是我们想统计指令时就会有很大问题了。比如我们可能会看到某个add指令导致了大量的分支预测错误,显然这个是不可能的。往往这种时候我们可以看看前面一点的指令。 - Interrupt Masking(中断屏蔽),导致统计出来的空闲状态比正常的高
不同的中断有不同的优先级,为了高优先级的中断处理程序不被打断,我们可以选择屏蔽一部分中断事件。但是PMU的事件也是一个中断,如果系统中有大量的中断屏蔽,那么会有PMU的中断被屏蔽掉一部分,导致统计出来的数据不准确。表现出来的效果就是,统计出来的处于空闲状态的时间比实际的要高。
总结
这几个就是比较常见的性能分析方法。我们知道了性能分析的原理,可以更好地理解性能分析器给出的结果,也可以在出现明显异常的结果时,分析判断可能的原因,针对性的解决。
参考
https://en.wikipedia.org/wiki/Profiling_(computer_programming)
https://software.intel.com/content/www/us/en/develop/articles/understanding-how-general-exploration-works-in-intel-vtune-amplifier-xe.html
https://software.intel.com/content/www/us/en/develop/documentation/vtune-help/top/analyze-performance/user-mode-sampling-and-tracing-collection.html
https://software.intel.com/content/www/us/en/develop/documentation/vtune-help/top/analyze-performance/hardware-event-based-sampling-collection.html
CPU性能分析工具原理的更多相关文章
- Linux性能优化:CPU性能分析工具--vmstat
Blog:博客园 个人 目录 参数说明 输出信息说明 procs memory swap io system cpu 示例 vmstat是Virtual Meomory Statistics(虚拟内存 ...
- CPU性能分析
CPU性能分析工具 lscpu:查看CPU硬件信息 lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Litt ...
- Linux下性能分析工具汇总
来自:http://os.51cto.com/art/201104/253114.htm 本文讲述的是:CPU性能分析工具.Memory性能分析工具.I/O性能分析工具.Network性能分析工具. ...
- 系统级性能分析工具 — Perf
从2.6.31内核开始,linux内核自带了一个性能分析工具perf,能够进行函数级与指令级的热点查找. perf Performance analysis tools for Linux. Perf ...
- Linux性能分析工具与图形化方法
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~. 作者:赵坤|腾讯魔王工作室后台开发工程师 在项目开发中,经常会遇到程序启动时间过长.CPU使用率过高等问题,这个时候需要依靠性能分析工具来 ...
- 系统级性能分析工具perf的介绍与使用[转]
测试环境:Ubuntu16.04(在VMWare虚拟机使用perf top存在无法显示问题) Kernel:3.13.0-32 系统级性能优化通常包括两个阶段:性能剖析(performance pro ...
- Linux 性能分析工具汇总合集
出于对Linux操作系统的兴趣,以及对底层知识的强烈欲望,因此整理了这篇文章.本文也可以作为检验基础知识的指标,另外文章涵盖了一个系统的方方面面.如果没有完善的计算机系统知识,网络知识和操作系统知识, ...
- [转]Linux性能分析工具汇总合集
出于对Linux操作系统的兴趣,以及对底层知识的强烈欲望,因此整理了这篇文章.本文也可以作为检验基础知识的指标,另外文章涵盖了一个系统的方方面面.如果没有完善的计算机系统知识,网络知识和操作系统知识, ...
- 超全整理!Linux性能分析工具汇总合集
转自:http://rdc.hundsun.com/portal/article/731.html?ref=myread 出于对Linux操作系统的兴趣,以及对底层知识的强烈欲望,因此整理了这篇文章. ...
随机推荐
- iOS不移除通知也不会崩溃原因
在iOS9.0之前,通知中心对观察者对象进行unsafe_unretained 引用,当被引用的对象释放时不会自动置为nil,,也就是成了野指针. iOS9.0之后通知中心对观察者做了弱引用. 参考: ...
- PHP设计模式(一)
1)工厂模式 工厂模式是用工厂方法生成对象,而不是直接new一个对象.假设我们在Config命名空间下有一个名叫Db的数据库操作类,用普通的方法,如果我们想去创建一个Db的对象,我们会直接new一个出 ...
- C#判断网址的可访问性
/// <summary> /// 判断网址是否可以访问 /// </summary> /// <param name="Url"></p ...
- pytest跟unittest的优势跟劣势
一.用例编写规则 1.使用unittest编写测试用例必须遵循以下规则: 1.必须首先 导入 import unittest 2.测试类必须要继承 unittest.TestCase 3.测试方法必须 ...
- Java之预定义
作为Java初学者的我,提供一个类似C#的预处理机制.若有不足之处,敬请各位大佬指正(感觉没有,哈哈哈哈哈哈)! Java 没有类似 C++的宏,也没有类似C#的预定义 #if...#endif C# ...
- [批处理教程之Shell]001.文本处理
在计算机科学中,Shell俗称壳(用来区别于核),是指“提供使用者使用界面”的软件(命令解析器).它类似于DOS下的command和后来的cmd.exe.它接收用户命令,然后调用相应的应用程序. 同时 ...
- [工具-006] C#如何模拟发包登录
最近接到一个任务,就是模拟某个贴吧的登录发帖功能,我的思路是通过IE浏览器的工具对登陆操作进行抓包,记录登录时候请求的URL,请求方式,请求正文等信息进行模拟的发包. 1.首先我们要到登陆页面,以摇篮 ...
- docker出现相同的image条目的删除办法
一.问题:在测试docker安装的prometheus系统时,由于异常操作,使用docker image ls出现了两条一模一样的条目,如下: [root@ELK prometheus]# docke ...
- Rocket - diplomacy - DUEB参数模型的设计
https://mp.weixin.qq.com/s/9PEEpe1pkQDN9RWpOGSUCQ 介绍DUEB参数模型的设计,不包含实现(实现对设计做了简化). 1. DUEB di ...
- (Java实现) 工作分配问题
工作分配问题 时间限制: 1 Sec 内存限制: 128 MB [提交][状态][讨论版] 题目描述 设有n件工作分配给n个人.为第i个人分配工作j所需的费用为c[i][j] .试设计一个算法,计算最 ...