计算机体系结构基础(第3版)
上QQ阅读APP看书,第一时间看更新

12.4 性能测试和分析实例

与1GHz主频的龙芯3A1000相比,2.5GHz主频的龙芯3A5000在主频只提升2.5倍的情况下实现了性能的10倍以上的提升。这个成绩背后是大量的性能分析和设计优化工作。本节以龙芯3A5000处理器的部分性能测试和分析工作为例,展示相关工具与方法的实际应用。

我们采用对比分析的方法,选择了两款采用类似工艺的X86处理器作为参考对象。对这三款处理器,我们先用SPEC CPU基准程序进行宏观性能测试,然后用perf工具收集SPEC CPU运行过程的微结构相关统计数据,用LMbench等微基准程序测量系统的一些关键参数,试图通过对比分析更好地理解不同设计对性能的影响,寻找下一代龙芯处理器可能的优化方向。

表12.14给出了这三款处理器的基本信息和主要设计参数。为了减少不必要的差异,三款处理器的频率被都设置为2.5GHz,测试软件也尽量采用相同的编译器及编译参数来编译。

表12.14 三款处理器的基本信息和主要设计参数

这三款处理器的总体微结构设计比较相近,但又各有特点。龙芯3A5000的“架子”(ROQ等队列大小和重命名寄存器数量等)明显小于其他两款,浮点功能部件数量少于其他两款,但它的三级Cache容量却是最大的;Skylake“架子”最大,有三个访存部件,但三级Cache容量最小,内存也相对慢。

12.4.1 SPEC CPU基准测试程序的分值对比

三款处理器的测试机采用的编译器均为GCC 8,使用基本相同(除个别处理器相关选项外)的SPEC CPU peak优化配置文件。表12.15和表12.16分别给出了三款处理器的SPEC CPU2006 speed和4核rate分值对比 SPEC CPU基准测试提供了两种分值指标:一种是测试计算机能多快完成一个任务,官方称为speed指标;另一种是测试计算机完成多个任务的吞吐率,官方称为rate指标。我们把同时启动4个任务的运行结果指标称为4核rate指标。

表12.15 SPEC CPU2006 speed分值对比

表12.16 SPEC CPU2006 rate4分值对比

基准测试程序的主要作用之一是评价目标产品的性能,比如SPEC CPU能够用于不同CPU之间的性能比较。通过上述数据,我们可以说3A5000定点性能和同频率的Zen处理器大致相当(SPECint2006平均相差4.2%),但浮点性能还有一定差距(SPECfp2006平均相差44.8%)。

通过基准程序的比较分析可以发现一些可能的优化方向。例如,从上述数据我们不难发现,3A5000的浮点性能有比较明显的提升空间。可以在相关设计平台上尝试增加浮点功能数量来验证是否能够显著提升性能,如果单纯增加浮点部件还不够,可以继续试验扩大“架子”来进一步确定。设计中的下一代龙芯处理器在这两个方面都做了较大的改进,有望弥补这个弱点。同样,我们也可以看到,并不是每个SPEC程序的性能差异都是一样的,有些程序3A5000快,有些Zen1快,有些Skylake快。其中定点程序性能差距最大的是462.libquantum,Zen1比3A5000快78.9%,显著大于其他定点程序。我们进一步分析这个程序,发现这和编译器的自动并行化支持有关系。在关闭编译器的自动并行化选项时,差距缩小到16.5%,如表12.17所示。除了462以外,436和459等几个程序的自动并行化效果在3A5000和Zen1上也有类似情况。因此,龙芯3A5000平台的编译器自动并行化优化的实现很可能存在较大的优化空间。此外,3A5000与另外两款处理器的SPEC CPU rate分值差距比speed更大,这一点和它拥有更大的三级Cache以及更高的访存速率不一致,需要进一步分析。类似这样,细致分析相关数据可以找到分析点,这里不再展开。

表12.17 SPEC CPU2006 speed分值对比(关闭自动并行化)

基准程序的比较分析还可以帮助我们理解微结构设计与程序性能之间的关系。不同的程序对不同的微结构参数敏感,观察每个程序在不同处理器上的表现,结合下节更多的微结构数据,可以更好地理解它们之间的关系。当然,众多微结构参数往往会以复杂的形式互相影响,不能轻易做出结论。有条件的情况下(例如有校准过的性能设计模型或者快速仿真平台),最好通过每次只改变一个参数来观察确认。

[1] SPEC CPU基准测试提供了两种分值指标:一种是测试计算机能多快完成一个任务,官方称为speed指标;另一种是测试计算机完成多个任务的吞吐率,官方称为rate指标。我们把同时启动4个任务的运行结果指标称为4核rate指标。

12.4.2 微结构相关统计数据

SPEC CPU的分数只能宏观体现一个程序的性能,我们需要收集更多微观运行时数据才能更好地了解程序的行为,比如程序执行了多少指令,花了多少时钟周期,有多少分支指令猜测错误,哪部分代码运行次数多,哪里Cache不命中最频繁,等等。利用12.3节介绍的perf工具就能够收集这类数据,本节展示了SPEC CPU2006动态指令数、IPC和分支预测相关的几个指标的情况。前两个是CPU性能公式中的两大要素,分支预测则对现代高性能处理器的性能有较大影响。

1.动态指令数

CPU的性能公式说明处理器的执行时间和CPI、时钟频率以及动态执行指令数相关。表12.18给出了3A5000、Zen1和Skylake三款处理器SPEC CPU2006动态执行指令数的对比,其中指令数目的单位为百万条,SPEC_int和SPEC_fp为定点程序和浮点程序指令数目的累积总和。

表12.18 SPEC CPU2006动态指令执行数目(百万条)的对比

对于CPU2006,3A5000定点程序比Zen1的动态指令数(累积总和)要多12.9%,浮点程序指令数(累积总和)要多13.0%。和Skylake相比,3A5000定点程序指令数要多19%,浮点程序平均要多26.2%。对于定点程序中403.gcc、456.hmmer、464.h264ref的指令数,3A5000比Zen1多25%以上;对于浮点程序中410.bwaves、416.gamess、434.zeusmp和481.wrf的指令数,3A5000比Zen1多30%以上。对比3A5000和Zen1的CPU2006的分值和动态指令数之间的关系,基本上符合动态指令数差距越大,性能差距也就越大。

动态指令数与指令集和编译器都有密切的关系。X86是一种复杂指令集,在动态指令数方面总体比RISC指令集略有优势是可以理解的,但超过20%的差距都值得认真查看。例如,以上数据中,对于436.cactusADM的动态指令数,3A5000比Skylake多超过一倍,即使是Zen1也比Skylake多将近一倍。查看相应的代码,可以发现主要是编译器的向量指令选择带来的差异。Skylake用256位向量指令,Zen1用128位。3A5000同样支持256位向量,但是其自动向量化支持尚不够优化,没有选择生成向量指令。按peak优化配置编译时,编译选项会指定处理器的微结构型号,如-march=native或-march=loongarch,GCC编译器会根据处理器的微结构型号选取合适的指令。例如对同一段源代码,对于Zen1,编译器可能会选取128位的向量指令,因为256位的向量指令在Zen1内部需要被拆分,其效率有时候还不如128的向量指令,而对于Skylake,编译器可能会选取256位的向量指令,这也导致同样是X86指令集的Zen1和Skylake动态指令数的不同。分析动态指令数的差异原因,可以为编译器和指令集的优化提供直接线索。

2.IPC

动态执行的指令数目只是性能公式中的一个因素,CPU性能公式的第二个因素是IPC。表12.19是三款处理器CPU2006测试程序IPC的对比。

表12.19 SPEC CPU2006 IPC的对比

从表中的数据可以看出3A5000的定点程序的IPC高于Zen1,略低于Skylake,3A5000的浮点程序的平均IPC低于Zen1和Skylake。

从IPC数据的演进可以看到处理器微结构的不断发展。对于SPEC CPU2006程序,3A2000和AMD K10的定点IPC平均为1左右,浮点IPC平均为1.1左右,而3A5000和Skylake的定点IPC平均提升到1.4左右,而Zen1的浮点IPC平均提升到1.73。

同样,IPC数据的对比分析也可以提供一些优化线索。例如,可以找到同一程序在不同处理器上IPC差异很大的情况,通过热点代码块比较、微结构行为数据统计等进一步分析相应的编译器和微结构是否存在瓶颈。

3.分支预测

分支指令处理的效率对处理器性能的影响较大,衡量分支指令处理效率的指标通常包括分支误预测率和分支指令的吞吐率。表12.20和表12.21给出了三款处理器SPEC CPU2006测试程序分支误预测率和分支吞吐率的对比。

表12.20 3A5000、Zen1、Skylake的SPEC CPU2006分支误预测率

表12.21 3A5000、Zen1、Skylake的SPEC CPU2006分支吞吐率(每秒钟执行百万条分支指令)

可以看到,这三款处理器总体分支误预测率的绝对值都已经比较小,Skylake整体表现最优秀,3A5000还有一定的提升空间。浮点程序总体误预测率比定点程序小。影响程序性能的除了分支误预测率还有分支解决速度、错误路径指令的取消效率等,这些可以在分支吞吐率指标中有所体现。进一步针对具体程序分析相关指标差距的根源,有助于不断改进分支预测的性能。

分支预测对整体性能的影响还和分支指令的比例有关系。表12.22显示了SPEC CPU2006程序中分支指令的比例。可以看到,浮点程序中分支指令的比例明显少于定点程序。结合相对较低的误预测率,我们可以说分支预测对浮点程序的影响相对较小。分析整体影响时要综合考虑误预测率和分支比例。例如,从单个程序的数据异常看,浮点程序433.milc在3A5000上的误预测率高达6.58%,显著高于Zen1的误预测率0.4%和Skylake的0.23%。但是这个程序的分支比例非常少,在3A5000中只占1.2%,在Zen1和Skylake中占2.1%,因此它对总体性能的影响也比较小。

表12.22 3A5000、Zen1、Skylake的SPEC CPU2006分支指令所占百分比

12.4.3 基础性能参数

Perf利用事件采样获取许多有用的微观运行数据,还有一些工具则从软件角度测量系统的一些基础性能参数,两者可以互相补充。例如,对于存储子系统,可以用Perf来统计各级存储的Cache命中率,用LMbench测试各级存储访问延迟和带宽等,从而获得更全面的理解。本节展示LMbench的部分应用案例。

1.存储访问延迟

在处理器的性能指标中,各级Cache的访存延迟是一个重要的参数,其决定如果Cache访问命中或者失效,需要多少拍能回来。图12.3给出了3A5000、Zen1、Skylake的各级Cache和内存的访存延迟比较数据,其为基于跳步(stride)的访存测试结果。这个测试应用LMbench中的存储延迟测试工具执行的命令为./lat_mem_rd 128M 4096,其中参数4096为跳步大小。其基本原理是,通过按给定间隔去循环读一定大小的内存区域,测量每个读平均的时间。如果区域大小小于一级Cache大小,时间应该接近一级的访问延迟;如果大于一级小于二级,则接近二级访问延迟;依此类推。图中横坐标为访问的字节数,纵坐标为访存的拍数(cycles)。

图12.3 基于跳步访问的3A5000、Zen1、Skylake各级延迟的比较

从图中可以看出,对于一级Cache的延迟,3A5000、Zen1、Skylake都为4拍;对于二级Cache、三级Cache和内存延迟,3A5000优于Zen1;对于二级和三级Cache的延迟,3A5000略优于Skylake,3A5000和Skylake内存访问延迟相似。

测试中还发现,通过变化stride参数的大小,当stride为64~1024字节时,3A5000和Skylake处理器的二级、三级和内存延迟没有显著的突变(断层),而Zen1处理器在stride为512字节时已经出现明显的断层,有可能Zen1的预取器覆盖范围较小。

规整的基于跳步的访存测试结果会受到处理器的硬件预取器的影响,如果采用随机访问预取器就比较难发挥作用。图12.4给出了3A5000、Zen1、Skylake的各级Cache和内存的随机访存延迟比较数据,执行的命令为./lat_mem_rd-t 128M 4096,其中参数4096为跳步的大小。基于随机访问的延迟比较接近相关存储的物理访问延迟。从图中可以看出,对于3A5000、Zen1、Skylake,一级Cache的延迟都为4拍,二级Cache的延迟分别为14拍、17拍和12拍,Skylake明显占优,三级Cache的延迟分别为38~45拍、38~49拍和38~48拍,内存延迟(随机访问)分别为228~344拍、286~298拍和164~221拍。3A5000在三级Cache的延迟上略微有优势,而Skylake在内存访问的延迟上有明显优势。从随机访问的内存延迟来看,当访问大小超过40MB时,3A5000的访存延迟会不断上升,一直到344拍,而Zen1和Skylake变化不大,基本维持在298拍和221拍左右,因此3A5000内存控制器可能存在改善空间。

图12.4 基于随机访问的3A5000、Zen1、Skylake各级延迟的比较

表12.23给出了3A5000、AMD Zen1、Zen+以及Intel的Skylake处理器的一级、二级和三级Cache以及内存访问延迟(cycles)的对比。2018年AMD公司推出Zen1的改进版Zen+,微结构基本没有变化,只是把二级、三级Cache和内存的访问延迟降低了,其SPEC CPU性能提高了3%,因此,各级Cache和内存访问的延迟会直接影响处理器的性能。

表12.23 3A5000和对比处理器的各级Cache和内存访问延迟数据

2.存储访问操作的并发性

图12.5给出了LMbench测试得到的访存操作的并发性,执行的命令为./par_mem。访存操作的并发性是各级Cache和内存所支持并发访问的能力。在LMbench中,访存操作并发性的测试需要设计一个链表,不断地遍历访问下一个链表中的元素。链表所跳的距离和需要测量的Cache容量相关,在一段时间能并发地发起对链表的追逐操作,也就是同时很多链表在遍历,如果发现这一段时间内能同时完成N个链表的追逐操作,就认为访存的并发操作是N。

图12.5 访存操作的并发性

从图中可以看出,3A5000的访存并发性和AMD的Zen1以及Intel的Skylake处理器基本相当,在三级Cache大小范围时略有优势。

3.功能部件延迟

表12.24列出了三款处理器的功能部件操作延迟数据,使用的命令是./lat_ops。

表12.24 3A5000、Zen1、Skylake的功能部件操作延迟

从测试数据来看,3A5000的定点操作延迟控制较好,多数优于其他两款处理器,但是浮点操作延迟则多数偏长,这也可能是其SPEC浮点程序性能落后的部分原因。当然,判断这些测试本身是否足够合理需要进一步分析相应的测试代码,不能无条件采用。LMbench的lat_ops说明文档中明确表示,这个测试程序是实验性的,有时(甚至经常)会给出误导的结论。性能分析工作中常见的误区之一就是被不准确甚至错误的数据误导,得出错误的结论。因此使用各种工具时,应该尽可能了解目标系统和工具的工作原理,对数据的合理性进行必要的判断。

4.STREAM带宽

LMbench包含STREAM带宽测试工具,可以用来测试可持续的内存访问带宽情况。表12.25列出了三款处理器的STREAM带宽数据,其中STREAM数组大小设置为1亿个元素,采用OpenMP版本同时运行四个线程来测试满载带宽。相应测试平台均为CPU的两个内存控制器各接一根内存条,3A5000和Zen1用DDR4 3200内存条,Skylake用DDR4 2400内存条(它最高只支持这个规格)。

表12.25 3A5000、Zen1、Skylake的STREAM带宽

从数据可以看出,虽然3A5000和Zen1在硬件上都实现了DDR4 3200,但3A5000的实测可持续带宽还是有一定差距。用户程序看到的内存带宽不仅仅和内存的物理频率有关系,也和处理器内部的各种访存队列、内存控制器的调度策略、预取器和内存时序参数设置等相关,需要进行更多分析来定位具体的瓶颈点。像STREAM这样的软件测试工具能够更好地反映某个子系统的综合能力,因而被广泛采用。