剖析的艺术:使用Intel VTune Amplifier,第2部分

原文:https://hadibrais.wordpress.com/2017/03/19/the-art-of-profiling-using-intel-vtune-amplifier-part-2/

Hadi Brais 著

       第1部分中,我已经介绍了VTune、剖析流程和剖析程序。剖析流程的第1步就是构建目标程序。在构建目标程序是打开编译优化选项是非常重要的。在这部分中,我将为分析类型进行介绍。

目的

       在做任何事之前,您必须确定剖析的目的。您想要分析的是什么?在该教程中,您要分析的是热点。热点是指计算机程序或计算机系统的某个区域,该区域是大量活动对系统其余部分具有重要意义。其中一个更为常用的定义请参考Wikipedia。通常, 感兴趣的活动是程序执行情况。在这里,一个热点将是程序的一个区域, 其中占执行时间的总和的很大一部分时间。

       查找热点不仅仅是用来剖析的唯一理由,还包括查找错误、发现并行化时机、理解线程工作或进程的相互交互、分析特定I/O设备部或系统资源利用率、。如果您想进行性能优化,却无从下手,可以参考性能提速方法(performance tuning methodology)。

       在该教程中,我将着手于查找密码破解程序的性能热点。

VTune工程及分析项

       VTune工程就是一个分析项集合。一个工程仅有两个属性:工程名及保存分析结果的目录。动手吧,创建一个工程,名称随您取(冷静一下,描述性的名称更可取)。

       一个VTune分析项是一对配置与剖析结果(在目标终止时生成)。在VTune GUI中,为配置分析项提供了两个标签,分析目标和分析类型。切换到分析目标标签页,选项合适的选项,参考这里(here)。

分析类型

       剖析技术可分为3种:采样、仪表、软件事件订阅。采样的过程是,周期性中断程序或系统,并在此时抓取它的状态信息。仪表的过程是,在程序中感兴趣的位置插入称为仪表器的代码片段,这些仪表器伴随程序一起执行,并收集程序的行为信息。一般来说,仪表比采样得到更为精确的结果,但随之开销也大得多。VTune同时使用这两种技术,它使用Pin 处理仪表器,并管理在运行的目标进程。软件事件订阅的过程是,它依赖于运行时或操作系统报告系统的行为事件,剖析器能订阅某些可监听的回调事件。VTune通过仪表及跟踪技术( Instrumentation and Tracing Technology (ITT) APIs.)来支持这种方式。以下是两种采样方式:

基于时间采样(TBS)

       基于时间采样,通常称为软件收集或用户模式采样及跟踪收集(User-Mode Sampling and Tracing Collection),利用时间定时器中断当前进程所有线程并抓取所需的信息。之所以称之为用户模式,是因为它在不需要内核驱动的情况下,就能进行抓取采样(与基于事件的采样相反)。

       我说一下它在Linux下是如何工作的。当VTune启动或关联到一个进程时,程序将调用setitimer(2)创建ITIMER_PROF定时器并传递一个数值作为采样间隔。即使程序也会使用setitimer函数,VTune会对这些调用进行模拟,剖析器会将它们排除在外。顺便一说,Windows下的等价函数是 SetTimer

       当一段约等于采样间隔的时间过去后,将会产生SIGPROF信号,操作系统将会选择其中一个线程来处理它。当然,VTune会为该信息注册处理器。处理器按适当的顺序执行下列操作:

决定是抓取一个采样,还是传递给程序处理,如果是后者,那么调用程序的处理器并返回。

挂起其余所有线程。

记录当前指令指针(IP)和每个线程的调用堆栈。

恢复其余所有线程。

       可编程的定时器会周期性发出信号。您可以设置VTune的采样间隔,在1到1000毫秒之间。实际上最小采样间隔要依赖于操作系统(OS dependent.)。

       一般来说,采样要做到正确是困难的。线程的创建、终止、动态库的加载和卸载都是需要跟踪的。更多内容参看这里(this )。感谢VTune,您大可不必担心这些问题。请注意, 由于它工作方式的原因,使用TBS进行整个系统剖析并不方便。

       TBS不依赖于任何特定硬件特性,仅仅是一个定时器就能工作。所以,您可以在Intel和非Intel处理器中使用TBS。以下是使用TBS的分析类型:

基本热点

并发

锁与等待

       TBS同时能用于任何虚拟机。

基于事件采样(EBS)

       基于事件采样,通常称为硬件收集或基于硬件事件采样收集(Hardware Event-based Sampling Collection),当某些事件中断发生时,Intel处理器将使用性能监视单元接收这些中断。它远比TBS强大得多,但只能用于Intel处理器。对于其他处理器,也有特定的剖析器,例如:AMD CodeXL 支持AMD处理器下的EBS。跟VTune一样,CodeXL在所有兼容处理器中支持TBS。每个逻辑内核 (硬件线程) 都有一个 PMU, 用于处理与该核心有关的事件。然而,多个逻辑内核也同时共享一个资源(如一个L2缓存),此时将共享一个事件集合。另外,还有个单独的PMU来处理一些非核心(L3缓存、内存控制器、QPI)的关联事件。

       事件计数器可以是可编程,也可以是固定的。在同一时刻,仅有少量的可编程计数器可用 (一般是4个)。固定计数器总是可用,但在溢出时不会被通知。更多采样的实现信息,请查阅下列文章:article 1article 2article 3

       检测热点时有非常多的特定事件可用(Haswell中定义的事件名称):

CPU_CLK_THREAD_UNHALTED.REF_XCLK:可编程计数器,用于获取递增计数器时钟,引用时钟(XCLK)频率,只有在硬件线程非中止状态时可用(有些软件线程被调度到硬件线程时,线程没有执行HLT指令或MWAIT指令)。它计数的是基准周期。主频为133MHz的Westmere和低一点的100MHz的Sandy Bridge就是这类。当超线程不可用时,CPU_CLK_UNHALTED.REF_XCLK计数可用;

CPU_CLK_UNHALTED.THREAD_P:可编程计数器,用于获取递增计数器,在当前时钟频率下硬件线程处于非中止状态时,换句话说就是钟周期数。注意动态频率或散热将会导致时钟周期产生变化。这些被称作核心周期相对于基准周期;

CPL_CYCLES.RING0:可编程计数器,用于获取递增计数器,在当前时钟频率下硬件线程处于非中止状态时运行在Rang 0级(特权模式)时;

PL_CYCLES.RING123:可编程计数器,用于获取递增计数器,在当前时钟频率下硬件线程处于非中止状态时运行在Rang 1,2,3级(非特权模式)时。该计数器与上个计数器可用于区分用户模式与内核模式的CPU利用率情况;

CPU_CLK_UNHALTED.REF_TSC:固定计数器,用于获取递增的计数器,在相同频率时的时间戳计数器(TSC)。等于参考频率乘以额定比率(非加速)(等于额定频率除以10^8)。参看可编程计数器CPU_CLK_THREAD_UNHALTED.REF_XCLK。

VTune使用这些计数器进行采样。每个逻辑核心有它自己的一套可编程计数器,每个核心可中断它运行的采样线程。当使用比较小的采样间隔时,相对于TBS这会导致少量开销。然而,对这些计数器在进行编程和使用时需要内核驱动程序(伴随VTune安装)。另外,如果剖析的程序同时也使用PMU,那么该功能将失效。

硬件性能计数器并不受限于特定的软件线程或进程,它们是系统范围的。所以如果您只对单个进程的剖析感觉兴趣,但其他潜在进程也运行于系统中,性能计数器所有描述的程序行为并不总是精确的。VTune会管理线程,不管它是否派发到核心上,使得性能计数器能够为特定进程保存独立的状态,这也就说明了为什么在剖析系统时只能使用有EBS。

我注意到了一点,在使用EBS时,VTune 不会禁用动态频率缩放,这是件好事。这才是程序被剖析时的真实行为。其他剖析器会禁用动态频率缩放或使用固定的最大频率,以方便中断计数器。也可能是VTune在处理相关事件时才会这么做。

我之前提到的分析类型使用的是TBS,其他所有类型使用EBS(All other analysis types use EBS)。在EBS下VTune支持采样间隔在0.01~1000毫秒之间。重申一遍,TBS的最小采样间隔远远小于1毫秒。最小间隔限制主要取决于硬件本身,最大间隔限制是因为更大的间隔对剖析并不用处。

对于EBS与TBS,在进行采样时,间隔不取决于硬件频率。要牢记的是,除了实时系统,在特定地频率下定时器的中断触发将是近似的。在一个间隔后,一次采样将不会发生,可能在之后的某个时间触发。

EBS能够用于支持硬件性能计数器虚拟化技术的虚拟机。详情请参考这里(this )。

采样vs.仪表

      之前已经提到,仪表相对于采样会带来更大的开销,但与此同时也带来了更为精确的程序行为描述。如果有函数的执行时间太短(小于采样间隔),VTune将无法剖析到这些函数。出于这个原因,VTune将会尽可能的收集调用堆栈。观察下面这个例子调用路径

func1 -> func2 -> func3

       如果func2执行时间太小,VTune可能无法抓取到这个函数的采样信息。那么剖析结果将会是如下调用路径:

func1 -> func3

       旧版本的VTune提供一个称为剖析调用图,利用动态二进制仪表的功能精确抓取调用图。遗憾的是,出于一些原因,在新版本已经移除了,VTune目前支持源代码级仪表(source level instrumentation)。

       如果您很想看到精确的调用图,您可以使用EBS并使用0.01毫秒,在大多数热点分析中都是有效的。通常您都不必这么做的,默认的1毫秒间隔已经是一个在剖析开销及精确度很好的平衡了。

       在该系列的下一部分中,我将进行配置分析,运行分析。