本系列是对于HPC应用性能分析涉及的主要方法论及Intel主流工具分享。理解这些方法论将有助于对性能分析结果的理解。同时方法论也可以推广到其他的硬件平台的分析上。除此之外后面也将介绍如何用Vtune, Advisor以及ITAC进行性能分析,以及在性能分析过程中这三种性能工具的区别与分工。
TopDown微架构分析方法(TMA)
TopDown分析方法通过对程序执行时流水线上的执行情况进行进一步抽象,量化了性能指标对执行情况的影响,解决了传统指标(缺失率(Cache Miss Rate和TLB Miss Rate)和每千条指令数(PKI)等)只能表示程度,而无法确定问题的严重性。
TopDown是一个基于事件的度量,它可以识别应用程序中的主要性能瓶颈。 它的目的是显示CPU的流水线在运行应用程序时的平均利用率。 以前,解释事件的框架依赖于计算CPU时钟周期(clock tick)------即确定多少CPU时钟周期被用于那种类型的操作(例如,由于L2缓存未命中)。 与之前不同,这一框架则是基于计算流水线的资源而来的。 要理解TopDown的特性描述,需要从高层次上探索一些底层的微架构概念。 微架构的许多细节在这个框架中被抽象出来,这使得使用者不必是硬件专家也可以使用和理解它。
现代高性能CPU的流水线构成相当复杂。如下图所示,流水线在概念上分为两部分,前端(Front-End)和后端(Back-End)。
添加图片注释,不超过 140 字(可选)
前端负责获取以体系结构指令表示的程序代码,并将其解码为一个或多个低级硬件操作,这被称为micro-ops(uOps)。然后在一个名为分配(allocation)的过程中,uOps被输送到后端。在分配之后,后端负责监控uOp的操作数(data operand)何时可用,并在可用的执行单元中执行uOp。 当uOp的执行完成后,我们把它称作执行完成(retirement),并且 uOp的结果会被提交到体系结构状态(CPU寄存器或写回内存)。通常情况下大多数uOps会完全通过流水线并退出,但有时预测获取的uOps可能会在退出前被取消------比如错误预测的分支。
流水线槽(pipe slot)表示处理一个uOp所需的硬件资源。自顶向下的特性描述假设对于每个CPU内核,在每个时钟周期上,有四个流水线槽可用。它使用专门设计的PMU事件来衡量这些流水线槽的利用率。流水线槽的状态在分配点(在上图中用星号标记)处获取,这里uOps离开前端并到达后端。在应用程序运行时可用的每个流水线槽将根据上面描述的简化流水线视图分为四类。
在任何周期中,流水线槽可以是空的,也可以用uOp填充。如果一个槽位在一个时钟周期内是空的,这将被归于停滞(stall)。需要对流水线槽进行分类,确定是流水线的前端部分还是后端部分造成了停滞。这里使用指定的PMU事件结果计算出来。TopDown特性描述的目标是确定主要的瓶颈,将停滞归因于前端或后端将会是一个关键的考虑点。如果停滞是由于前端无法用uOp填充槽造成的,那么在此周期它将被归类为前端约束,这意味着性能受到前端约束类别下的某些瓶颈的限制。如果前端已准备好uOp,但由于后端尚未准备好处理它而因此无法交付它,则空流水线槽将被分类为后端绑定类别。 后端停滞(backend stalls)通常是由后端耗尽某些资源(例如,负载缓冲区)造成的。
如果处理器没有停止,那么流水线插槽将在分配点被uOp填满。 在本例中,如何对槽进行分类的决定因素是uOp最终是否执行完成。 如果它执行完成了,这个槽被归类为完成。 如果没有,无论是由于前端的不正确的分支预测,还是由于自修改代码导致的流水线刷新之类的清除事件,该槽将被归类为Bad Speculation。这四个类别构成了自顶向下描述的最高级。为了描述一个应用程序,每个流水线槽被精确地分为以下四类之一,如下图所示。
添加图片注释,不超过 140 字(可选)
更详细的划分会根据硬件平台不同有不同层次的支持,如图3所示。目前Intel官方资料上最多可细分至6层性能指标,但根据处理器平台的支持程度不同,大部分可以至少细分至4层。
添加图片注释,不超过 140 字(可选)
TMA既可用于对应用的负载特征的分析,也可以用于对应用的优化。TMA用于负载特征的分析,表现出应用在不同硬件平台上的运行时特征,为硬件选型提供参考。也可以应用类型,来判断应用性能指标是否异常,找出优化方向。如下图所示,不同的应用类型在TMA分析上有不同的表现。
添加图片注释,不超过 140 字(可选)
对应用进行性能优化,通常关注于热点函数分析。针对热点函数的优化,通常能够带来有效的性能收益。对热点函数分析通常可来自于三个层次的调整:1、系统参数层面;2、应用逻辑层面;3、微架构层面。但这也要具体问题具体分析,TMA适合于微架构层面的分析,通过找到在CPU上的硬件性能瓶颈,可以从编译参数角度,以及代码逻辑角度进行优化。从而达到优化的目的。
OpenMP*分析
针对OpenMP部分的性能考量主要来自于4个方面的考虑:
1、 串行时间的比例:OpenMP是通过对特定程序区域利用并行化来加速应用,是一种Fork---Join模式的并行模式。串行时间的比例可以体现程序的并行优化程度。
2、 负载不平衡:通常情况下OpenMP区域的负载都是均衡的,不均衡会使得并行优化在部分时间段内失效,比如因单个线程执行问题导致并行阶段延长。引发不均衡的情况有很多。可结合程序逻辑以及运行时CPU信息,来分析造成此现象得愿意。
3、 并行设置过大:并行区域的并行线程超过了循环次数,使得线程切换切换等待开销超过了并行优化带来的性能收益。
4、 同步锁分析: 在OpenMP区域内同步锁的设置不合理,产生锁竞争。增加没用的时间开销。