现代CPU性能分析与优化:Roofline性能模型详解
现代CPU性能分析与优化:Roofline性能模型详解
Roofline性能模型是一个以吞吐量为导向的性能模型,在高性能计算(HPC)领域广泛使用。它于2009年在加州大学伯克利分校开发。模型中的"roofline"表示应用程序的性能不能超过机器的能力。程序中的每个函数和每个循环都受到机器的计算或内存容量的限制。
硬件有两个主要限制:计算速度(峰值计算性能,FLOPS)和数据移动速度(峰值内存带宽,GB/s)。应用程序的最大性能受峰值FLOPS(水平线)和平台带宽乘以运算强度(对角线)两者之间的最小值限制。图中的roofline图将两个应用程序A和B的性能与硬件限制进行了对比。应用程序A的运算强度较低,其性能受内存带宽限制,而应用程序B的计算密集型程度更高,因此不会受到内存瓶颈的太大影响。类似地,A和B可以代表程序中的两个不同函数,并具有不同的性能特征。Roofline性能模型会考虑到这一点,可以在同一个图表上显示应用程序的多个函数和循环。
算术强度(AI)是FLOPS和字节之间的比率,可以针对程序中的每个循环进行提取。
代码清单:朴素并行矩阵乘法。
void matmul(int N, float a[][2048], float b[][2048], float c[][2048]) {
#pragma omp parallel for
for(int i = 0; i < N; i++) {
for(int j = 0; j < N; j++) {
for(int k = 0; k < N; k++) {
c[i][j] = c[i][j] + a[i][k] * b[k][j];
}
}
}
}
让我们计算代码的算术强度。在最内层的循环体中,我们有一个加法和一个乘法;因此,我们有2个FLOP。此外,我们还有三个读取操作和一个写入操作;因此,我们传输了4 ops * 4 bytes = 16个字节。该代码的算术强度为2 / 16 = 0.125。AI是给定性能点的X轴上的值。
传统的应用程序性能提升方式是充分利用机器的SIMD和多核能力。通常情况下,我们需要优化多个方面:向量化、内存、线程。Roofline方法可以帮助评估应用程序的这些特性。在roofline图表上,我们可以绘制标量单核、SIMD单核和SIMD多核性能的理论最大值
这将使我们了解改进应用程序性能的空间。如果我们发现我们的应用程序受计算绑定(即具有高算术强度)并且低于峰值标量单核性能,我们应该考虑强制向量化并将工作分发到多个线程上。相反,如果应用程序的算术强度低,我们应该寻求改善内存访问的方法。使用Roofline模型优化性能的最终目标是向上移动这些点。向量化和线程化向上移动点,而通过增加算术强度优化内存访问则会将点向右移动,并且可能也会提高性能。
理论最大值(roofline)通常在设备规范中给出,可以很容易地查阅。您也可以根据您使用的机器的特性计算理论最大值。一旦您知道机器的参数,这通常并不难做。对于Intel Core i5-8259U处理器,使用AVX2和2个Fused Multiply Add (FMA)单元的最大FLOP数(单精度浮点)可以计算如下:
峰值FLOPS = 8 (逻辑核心数量) × 256 (AVX位宽) / 32位 (float大小) × 2 (FMA) × 3.8 GHz (最大睿频) = 486.4 GFLOPs
我用于实验的Intel NUC Kit NUC8i5BEH的最大内存带宽可以如下计算。请记住,DDR技术允许每次内存访问传输64位或8个字节。
峰值内存带宽 = 2400 (DDR4内存传输速率) × 2 (内存通道) × 8 (每次内存访问的字节数) × 1 (插槽) = 38.4 GiB/s
像Empirical Roofline Tool: https://bitbucket.org/berkeleylab/cs-roofline-toolkit/src/master/2和Intel Advisor: https://software.intel.com/content/www/us/en/develop/tools/advisor.html3这样的自动化工具能够通过运行一组预先准备的基准测试来经验性地确定理论最大值。如果一个计算可以重用缓存中的数据,则可以实现更高的FLOP速度。Roofline可以通过为每个内存层次引入专门的roofline来实现这一点(
确定硬件限制后,我们可以开始评估应用程序相对于roofline的性能。用于自动收集Roofline数据的两种最常用方法是采样(由likwid: https://github.com/RRZE-HPC/likwid4工具使用)和二进制插桩(由Intel软件开发仿真器(SDE: https://software.intel.com/content/www/us/en/develop/articles/intel-software-development-emulator.html5)使用)。采样在数据收集方面产生的开销较低,而二进制插桩则能提供更准确的结果。6Intel Advisor自动构建Roofline图表,并为给定循环的性能优化提供提示。下图展示了Intel Advisor生成的Roofline图表示例。请注意,Roofline图表使用的是对数刻度。
Roofline方法可以通过在同一个图表上打印"之前"和"之后"的点来跟踪优化进度。因此,它是一个迭代的过程,指导开发人员帮助他们的应用程序充分利用硬件功能。图中显示了对之前代码进行以下两个更改所带来的性能提升:
- 交换两个最内层的循环(交换第4和第5行)。这可以实现缓存友好的内存访问(参见[@sec:MemBound])。
- 使用AVX2指令启用最内层循环的自动向量化。
总结来说,Roofline性能模型可以帮助:
- 识别性能瓶颈。
- 指导软件优化。
- 确定优化何时结束。
- 相对于机器能力评估性能。
其他资源和链接:
- NERSC文档,网址:https://docs.nersc.gov/development/performance-debugging-tools/roofline/
- 劳伦斯伯克利国家实验室研究,网址:https://crd.lbl.gov/departments/computer-science/par/research/roofline/
- 关于Roofline模型和Intel Advisor的视频演示集合,网址:https://techdecoded.intel.io/ (搜索 "Roofline")
- Perfplot是一个脚本和工具集合,允许用户在最近的Intel平台上测量性能计数器,并使用结果生成roofline和性能图。网址:https://github.com/GeorgOfenbeck/perfplot
- Empirical Roofline Tool - https://bitbucket.org/berkeleylab/cs-roofline-toolkit/src/master/. ↩
- Intel Advisor - https://software.intel.com/content/www/us/en/develop/tools/advisor.html. ↩
- Likwid - https://github.com/RRZE-HPC/likwid. ↩
- Intel SDE - https://software.intel.com/content/www/us/en/develop/articles/intel-software-development-emulator.html. ↩
- 在此演示文稿中,可以看到更详细的收集roofline数据的方法比较:https://crd.lbl.gov/assets/Uploads/ECP20-Roofline-4-cpu.pdf ↩