发表时间: 2009-04 · Communications of the ACM 52(4) (UC Berkeley)
原文: https://people.eecs.berkeley.edu/~kubitron/cs252/handouts/papers/RooflineVyNoYellow.pdf
作者/机构: Samuel Williams, Andrew Waterman, and David Patterson, Parallel Computing Laboratory, U.C. Berkeley
本文针对当前多核处理器设计多样化给程序员、编译器编写者和架构师带来的挑战,提出了一个易于理解的可视化性能模型——Roofline模型。随着行业向多核架构转型,传统同构设计的共识不复存在,出现了诸如“多而简”核与“少而精”核、多线程、本地存储替代缓存等多种设计,这加剧了软件优化的难度。因此,一个能够提供性能指导的简洁模型尤为重要。
核心问题与研究目标:
* 问题: 多核架构的多样性使得性能优化变得复杂,缺乏一个统一、易懂的指导模型。
* 目标: 提出一个像缓存领域的3Cs模型【19,M. Hill and A. Smith, "Evaluating Associativity in CPU Caches," IEEE Trans. on Computers, 1989】一样,虽不完美但富有洞察力的模型,帮助相关人员改进并行软硬件设计。
创新点(Roofline模型):
1. 核心理念: 该模型基于一个关键洞察——在可预见的未来,片外内存带宽通常是性能的瓶颈资源【23,D. Patterson, “Latency Lags Bandwidth,” CACM, 2004】。因此,模型的核心是将处理器性能与片外内存流量联系起来。
2. 关键度量衡“计算强度” (Operational Intensity): 定义为每次DRAM访问所执行的浮点运算次数(Flops/Byte)。它衡量的是经过缓存层次过滤后,在缓存与主存之间的流量,而非处理器与缓存之间的流量。这使得模型的边界和瓶颈分析能够包含计算机的内存优化效果。
3. 可视化表示: 模型采用对数-对数坐标图,Y轴为可达到的浮点性能(GFlops/sec),X轴为计算强度。
* 性能上限(“屋顶”): 由两条线构成:一条代表处理器峰值浮点性能的水平线,和一条代表峰值内存带宽的斜线。一个计算核心(kernel)的性能上限由这两条线的下界决定,即可达 GFlops/sec = Min(峰值浮点性能, 峰值内存带宽 × 计算强度)。
* 计算/内存瓶颈判断: 根据一个核心的计算强度,其性能点落在屋顶的水平部分(计算瓶颈)或倾斜部分(内存瓶颈)。
本文通过在四种不同的多核计算机上对四个关键浮点计算核心进行分析,验证了Roofline模型的有效性,证明了它能够为并行软件和硬件的性能改进提供深刻的洞察。
现有模型的局限性: 随机分析模型【14, M. Dubois and F. A. Briggs, “Performance of Synchronized Iterative Processes in Multiprocessor Systems,” IEEE Trans. on Software Engineering, 1982】【28, A. Thomasian and P. Bay, “Analytic Queueing Network Models for Parallel Processing of Task Systems,” IEEE Trans. on Computers, 1986】和统计性能模型【7, E. Boyd, et al, “A Hierarchical Approach to Modeling and Improving the Performance of Scientific Applications on the KSR1,” Proc. 1994 Int’l Conf. on Parallel Processing, 1994】【27, M. Tikir, et al, "A Genetic Algorithms Approach to Modeling the Performance of Memorybound Computations," Supercomputing (SC07), 2007】虽然能准确预测多处理器上的程序性能,但它们很少能提供关于如何改进程序、编译器或计算机性能的见解【1, V. Adve, Analyzing the Behavior and Performance of Parallel Programs, PhD thesis, 1993】,或者对于非专家来说难以使用【27】。
边界与瓶颈分析方法: 与其预测性能,这种更简单的方法提供了对影响计算机系统性能主要因素的宝贵洞察,特别是突显并量化了系统瓶颈的关键影响【20, E. Lazowska, et al, Quantitative System Performance: Computer System Analysis Using Queueing Network Models, 1984】。最著名的例子是阿姆达尔定律【3, G. Amdahl, “Validity of the Single Processor Approach to Achieving Large-Scale Computing Capabilities,” AFIPS Conference Proceedings, 1967】,它指出并行计算机的性能增益受限于并行程序的串行部分。该定律最近也被应用于异构多核计算机【4, K. Asanovic, et al. “The landscape of parallel computing research: A view from Berkeley.” Tech. Rep. UCB/EECS-2006-183, 2006】【18, M. Hill and M. Marty, “Amdahl's Law in the Multicore Era,” IEEE Computer, 2008】。
模型基础: 我们认为,在近期的过去和可预见的未来,片外内存带宽将常常是制约性资源【23, D. Patterson, “Latency Lags Bandwidth,” CACM, 2004】。因此,我们希望建立一个能将处理器性能与片外内存流量关联起来的模型。
计算强度的定义: 为此,我们使用“计算强度”(operational intensity)这一术语,表示每字节DRAM流量对应的运算次数。我们定义总访问字节数为经过缓存层次过滤后到达主存的字节数。也就是说,我们测量的是缓存与内存之间的流量,而不是处理器与缓存之间的流量。因此,计算强度暗示了一个核心(kernel)在特定计算机上所需的DRAM带宽。
术语选择的原因: 我们使用“计算强度”而非“算术强度”(arithmetic intensity)【16, M. Harris, "Mapping Computational Concepts to GPUs," ACM SIGGRAPH Tutorials, 2005】或“机器平衡”(machine balance)【8, D. Callahan, J. Cocke, and K. Kennedy. “Estimating interlock and improving balance for pipelined machines,” J. Parallel Distrb. Comput., 1988】【11, S. Carr and K. Kennedy, “Improving the Ratio of Memory Operations to Floating-Point Operations in Loops,” ACM TOPLAS, 1994】有两个原因。首先,算术强度和机器平衡衡量的是处理器与缓存间的流量,而我们希望衡量缓存与DRAM间的流量。这一微小改变使我们能将计算机的内存优化纳入我们的边界与瓶颈模型中。其次,我们认为该模型也适用于非算术运算的核心(见第7节),因此需要一个比“算术”更通用的术语。
模型构建: 所提出的模型在一个二维图中将浮点性能、计算强度和内存性能联系起来。峰值浮点性能可以通过硬件规格或微基准测试找到。我们在此考虑的核心的工作集不能完全放入片上缓存,因此峰值内存性能由缓存后的内存系统定义。尽管可以通过STREAM基准测试【22, J. McCalpin, “STREAM: Sustainable Memory Bandband in High Performance Computers,” 1995】找到内存性能,但在这项工作中,我们编写了一系列逐步优化的微基准测试,旨在确定可持续的DRAM带宽。它们包含了所有获取最佳内存性能的技术,包括预取和数据对齐。(附录A.1详细介绍了如何测量处理器和内存性能以及计算强度。)
模型的可视化: 图1a展示了一个2.2 GHz AMD Opteron X2 model 2214双路系统的模型。该图为对数-对数坐标。Y轴是可达到的浮点性能。X轴是计算强度,范围从1/4 Flops/DRAM字节到16 Flops/DRAM字节。被建模的系统具有17.6 GFlops/sec的峰值双精度浮点性能和我们基准测试得出的15 GBytes/sec的峰值内存带宽。后一个指标是计算机内存的稳态带宽潜力,而不是DRAM芯片的引脚带宽。
性能边界的形成: 我们可以绘制一条水平线,显示计算机的峰值浮点性能。显然,一个浮点核心的实际浮点性能不能高于这条水平线,因为这是一个硬件限制。峰值内存性能可以通过一条45度角的斜线表示,因为Y轴单位是GFlops/秒,X轴单位是GFlops/字节,两者的比值(字节/秒)在这张图上就是一条斜线。因此,我们可以绘制第二条线,它给出了在该计算机的内存系统支持下,对于给定的计算强度所能达到的最大浮点性能。这个公式驱动了图1a中的两个性能限制:
可达 GFlops/sec = Min(峰值浮点性能, 峰值内存带宽 × 计算强度)
这两条线在峰值计算性能和峰值内存带宽的点上相交。请注意,这些限制是为每台多核计算机创建一次,而不是为每个核心创建一次。
模型应用: 对于一个给定的核心,我们可以根据其计算强度在X轴上找到一个点。如果我们通过该点画一条(粉色虚线)垂直线,那么该核心在该计算机上的性能必定位于这条线上的某个位置。水平线和斜线构成了这个边界模型的名称——Roofline模型。Roofline模型根据核心的计算强度设定了其性能的上限。如果我们将计算强度想象成一根撞向屋顶的柱子,它要么撞到屋顶的平坦部分,意味着性能受计算限制;要么撞到倾斜部分,意味着性能最终受内存限制。在图1a中,计算强度为2的核心是计算受限的,而计算强度为1的核心是内存受限的。给定一个Roofline图,你可以重复地将其用于不同的核心,因为Roofline图本身不会改变。
屋脊点的意义: 注意,屋脊点(ridge point),即斜顶与平顶相遇之处,为计算机的整体性能提供了洞察。屋脊点的x坐标是达到最大性能所需的最小计算强度。如果屋脊点非常靠右,那么只有计算强度非常高的核心才能达到该计算机的最大性能。如果它非常靠左,那么几乎任何核心都有可能达到最大性能。正如我们将在第6.3.5节看到的,屋脊点暗示了程序员和编译器编写者为达到峰值性能所需付出的努力程度。
模型实例对比: 为了说明这一点,让我们比较图1a中的双核Opteron X2与其后继者四核Opteron X4。为了简化主板设计,它们共享相同的插槽。因此,它们具有相同的DRAM通道,从而可以拥有相同的峰值内存带宽,尽管X4的预取功能更好。除了核心数量翻倍外,X4每个核心的峰值浮点性能也翻了一番:X4核心每个时钟周期可以发射两条浮点SSE2指令,而X2核心每两个时钟周期可以发射两条。由于时钟频率略快——X2为2.2 GHz,X4为2.3 GHz——因此X4的峰值浮点性能略高于X2的四倍,而内存带宽相同。图1b比较了两个系统的Roofline模型。正如预期的那样,屋脊点从Opteron X2的1.0向右移动到Opteron X4的4.4。因此,要在X4上看到性能提升,核心的计算强度需要高于1。
优化指导: Roofline模型给出了性能的上限。假设你的程序性能远低于其Roofline。你应该执行哪些优化,以及按什么顺序执行?边界与瓶颈分析的另一个优点是“可以同时处理多个备选方案,通过单一的边界分析为所有方案提供有用的信息”【20, E. Lazowska, et al, Quantitative System Performance: Computer System Analysis Using Queueing Network Models, 1984】。我们利用这一洞察,为Roofline模型添加多个天花板,以指导选择何种优化,这类似于循环平衡为编译器提供的指导。我们可以将每种优化视为相应Roofline下的一个“性能天花板”,意味着不执行相关优化就无法突破该天花板。
计算瓶颈优化: 例如,为了减少Opteron X2上的计算瓶颈,有两种优化几乎对任何核心都有帮助:
内存瓶颈优化: 为了减少内存瓶颈,三种优化可以提供帮助:
天花板的确定与应用: 就像计算Roofline一样,计算天花板可以来自优化手册【2, AMD, Software Optimization Guide for AMD Family 10h Processors, 2008】,尽管也很容易想象通过简单的微基准测试来收集必要的参数。内存天花板需要对每台计算机进行实验,以确定它们之间的差距(见附录A.1)。好消息是,像Roofline一样,天花板也只需要为每台多核计算机测量一次。
天花板的可视化: 图2在图1a的Roofline模型中加入了天花板:图2a显示了计算天花板,图2b显示了内存带宽天花板。虽然较高的天花板没有用较低的优化来标记,但它们是隐含的:要突破一个天花板,你需要已经突破了它下面的所有天花板。图2a显示了计算“天花板”:如果浮点操作组合不平衡,性能上限为8.8 GFlops/sec;如果同时缺少增加ILP或SIMD的优化,性能上限为2.2 GFlops/sec。图2b显示了内存带宽天花板:没有软件预取时为11 GBytes/sec,如果也没有内存亲和性优化则为4.8 GBytes/sec,如果只有单位步长优化则为2.7 GBytes/sec。
综合模型与优化区域: 图2c将其他两张图合并成一个图。核心的计算强度决定了其所处的优化区域,从而决定了应该尝试哪些优化。图2c的中间部分显示,计算优化和内存带宽优化存在重叠。颜色的选择是为了突出这种重叠。例如,核心2落在右侧的蓝色梯形区域,这表明只需进行计算优化。如果一个核心落在左下角的黄色三角形区域,模型会建议只尝试内存优化。核心1落在中间的绿色(=黄色+蓝色)平行四边形区域,这表明两种类型的优化都应尝试。注意,核心1的垂直线位于浮点不平衡优化的下方,因此优化2可以跳过。
天花板的指导作用: Roofline模型的天花板建议了应该执行哪些优化。一个天花板与下一个更高天花板之间的高度差就是尝试该优化的潜在回报。因此,图2表明,优化1(提高ILP/SIMD)对于提高该计算机的计算性能有很大的潜在好处,而优化4(提高内存亲和性)对于提高该计算机的内存带宽有很大的潜在好处。
优化顺序与模型灵活性: 天花板的顺序建议了优化的顺序,我们从下到上排列天花板:最可能由编译器实现或程序员稍加努力就能实现的在底部,而难以由程序员实现或核心本身固有的在顶部。一个特殊情况是浮点平衡,因为实际的混合比例取决于核心。对于大多数核心来说,实现乘法和加法的均等非常困难,但对于少数核心来说,均等是自然的。一个例子是稀疏矩阵向量乘法。对于该领域,我们会将浮点混合比例作为最低的天花板,因为它是固有的。就像3Cs模型一样,只要Roofline模型能提供洞察,它就不必是完美的。
计算强度的可变性: 计算强度告诉我们应该关注哪些天花板。到目前为止,我们一直假设计算强度是固定的,但实际上并非如此。例如,有些核心的计算强度会随着问题规模的增大而增加,比如稠密矩阵和FFT问题。
缓存优化与计算强度: 显然,缓存会影响访问内存的次数,因此改善缓存性能的优化会增加计算强度。因此,我们可以将3Cs模型【19, M. Hill and A. Smith, "Evaluating Associativity in CPU Caches," IEEE Trans. on Computers, 1989】与Roofline模型联系起来。强制性未命中(Compulsory misses)设定了最小的内存流量,从而决定了可能达到的最高计算强度。由冲突(conflict)和容量(capacity)未命中产生的内存流量会显著降低核心的计算强度,因此我们应设法消除这类未命中。
提高计算强度的例子: 例如,我们可以通过填充数组来改变缓存行寻址,从而减少冲突未命中带来的流量。第二个例子是,一些计算机有非分配写(no-allocate store)指令,使得写操作直接进入内存而不影响缓存。这种优化避免了为将被覆盖的数据加载缓存块,从而减少了内存流量。它还防止了用不会被读取的数据替换掉缓存中有用的项目,从而节省了冲突未命中。
优化策略调整: 计算强度的这种向右移动可能会使一个核心进入不同的优化区域。通常的建议是在进行其他优化之前,先提高核心的计算强度。
本文选择了四种各具特色的双路多核计算机系统进行模型演示,其关键特性如表1所示。
本文没有选择标准并行基准套件(如Parsec【5】或Splash-2【30】),而是受科学计算专家Phil Colella【10】的启发,从他提出的对未来科学与工程至关重要的“七个矮人”中选取了四个核心进行演示。这些核心在较高层次上定义,允许跨实现进行行为推理。本文使用了针对每个核心的自动调优器【12】【25】【26】来生成针对特定多核计算机的最佳代码。
图3和图4展示了四台计算机的Roofline模型,并标出了各个核心优化后的性能点(红色X)和计算强度(粉色虚线)。由于SpMV核心天然地实现了乘法和加法操作的平衡,而其他核心则难以做到,因此针对Xeon、X4和Cell,本文为SpMV和其他三个核心分别绘制了不同的图(乘加平衡天花板位置不同)。T2+由于硬件限制,只有一个统一的Roofline图。
表4总结了每个核心-计算机组合的性能、带宽以及其所处的性能天花板区间。
谬误:模型未考虑缓存或预取等现代处理器特性。
澄清:本文中计算强度的定义确实考虑了缓存:内存访问是在缓存和内存之间测量的,而不是处理器和缓存之间。第2节表明,计算机的内存带宽测量确实包含了预取和任何其他可以提高内存性能的优化,如分块。同样,表3中的一些优化明确涉及内存。此外,第5节展示了它们通过减少容量和冲突未命中来增加计算强度的效果。
谬误:将缓存大小加倍会增加计算强度。
澄清:对四个核心中的三个进行自动调优后,其内存流量非常接近强制性流量;事实上,最终的工作集有时只占缓存的一小部分。增加缓存大小仅有助于解决容量未命中和可能的冲突未命中,因此对于这三个核心,更大的缓存对计算强度可能没有影响。然而,对于128³的3-D FFT,一个大的缓存可以容纳3-D立方体的一个完整平面,这通过减少容量和冲突未命中来提高计算强度。
谬误:模型没有考虑长内存延迟。
澄清:图3和图4中没有软件预取的天花板之所以处于较低的内存带宽,正是因为它们无法隐藏长内存延迟。
谬误:你需要为每个核心重新计算模型。
澄清:Roofline模型只需要为给定的性能指标和计算机计算一次,然后就可以指导任何以该指标为关键性能指标的程序设计。本文中的例子使用了浮点运算和内存流量。天花板是测量一次的,但可以根据核心中乘法和加法是否自然平衡而重新排序(见第4节)。
谬误:模型忽略了浮点程序中的整数单元,这可能限制性能。
澄清:对于本文中的例子,整数代码的数量和整数性能确实会影响性能。例如,Sun UltraSPARC T2+每个核心每个时钟周期取两条指令,并且没有x86那样的SIMD指令可以一次操作两个双精度浮点操作数。相对于其他处理器,T2+执行更多的整数指令,且执行速率较低,这损害了整体性能。
谬误:模型与多核无关。
澄清:利特尔法则【21, J. D. C. Little, "A Proof of the Queueing Formula L = λ W" Operations Research, 1961】【20】【17】指出,要真正挑战内存系统的极限,相当大的并发性是必需的。这种并发性在多核处理器中比在单核处理器中更容易满足。虽然Roofline模型的带宽导向对单核处理器也适用,但对多核处理器更有帮助。
谬误:模型仅限于那些容易优化且从不命中缓存的核心。
澄清:首先,这些核心确实在缓存中命中。例如,我们带有片上缓存的三个多核处理器上,stencil的缓存命中率至少为94%,FFT至少为98%。其次,如果这些“矮人”核心易于优化,那对多核的未来将是好兆头。然而,我们的经验是,在本文介绍的这些迥异的多核架构上创建这些数值方法的最快版本并不容易。事实上,其中三个结果被认为足够重要,已被主要会议接受发表【12, K. Datta, et al, “Stencil Computation Optimization and Autotuning on State-of-the-Art Multicore Architectures,” SC08, 2008】【25, S. Williams, et al, "Lattice Boltzmann Simulation Optimization on Leading Multicore Platforms," IPDPS, 2008】【26, S. Williams, et al, "Optimization of Sparse Matrix-Vector Multiplication on Emerging Multicore Platforms," SC07, 2007】。
谬误:模型仅限于浮点程序。
澄清:本文的重点确实是浮点程序,因此模型的两个轴是每秒浮点运算次数和主存访问的浮点计算强度。然而,我们相信Roofline模型可以适用于性能是不同性能指标函数的其他核心。一个具体的例子是3-D FFT的转置阶段,它根本不进行浮点运算。图5展示了仅针对Cell上这一阶段的Roofline模型,其中用“交换”(exchanges)代替了模型中的“Flops”。一次交换涉及读写16字节,因此其计算强度为1/32。请注意,尽管计算指标是内存交换,但仍然存在一个计算性的水平Roofline,因为本地存储和缓存可能会影响进入DRAM的交换次数。
谬误:Roofline模型必须使用DRAM带宽。
澄清:如果工作集能放入L2缓存,那么斜线Roofline可以是L2缓存带宽而不是DRAM带宽,X轴上的计算强度将基于每L2缓存字节访问的Flops。斜向的内存性能线会向上移动,屋脊点肯定会向左移动。例如,Jike Chong将两个金融PDE求解器移植到另外四种多核计算机上:Intel Penryn和Larrabee以及NVIDIA G80和GTX280【9, J. Chong, Private Communication, 2008】。他使用Roofline模型来追踪平台的峰值算术吞吐量以及L1、L2和DRAM带宽。通过分析算法的工作集和计算强度,他能够使用Roofline模型快速估计算法改进的需求。具体来说,对于使用隐式PDE求解器的期权定价问题,工作集小到足以放入L1,且L1带宽足以支持峰值算术吞吐量,因此Roofline模型表明无需优化。对于使用显式PDE公式的期权定价,工作集太大无法放入缓存,Roofline模型则有助于指示需要多大程度的缓存分块才能提取峰值算术性能。
从串行计算到并行计算的巨变增加了程序员在制作正确、高效、可扩展和可移植软件时必须面对的计算机多样性【4】。本文描述了一个简单而可视化的模型,以帮助观察哪些系统能与重要的核心良好匹配,或者反过来看,如何改变核心代码或硬件以良好地运行所需的核心。对于不能完全放入缓存的浮点核心,我们展示了计算强度——即每从DRAM传输一个字节所执行的浮点运算次数——对于核心和多核计算机都是一个重要参数。
我们将该模型应用于来自“七个矮人”【10】【4】的四个核心,在四种近期多核设计上进行了验证:AMD Opteron X4、Intel Xeon、IBM Cell和Sun T2+。屋脊点——达到最大性能所需的最小计算强度——被证明是比时钟频率或峰值性能更好的性能预测指标。Cell在这些核心上提供了最高的性能,但T2+是实现其最高性能最容易的计算机。一个原因是T2+的Roofline模型屋脊点是最低的。
仅仅是图形化的Roofline就能提供关于实现计算机峰值性能难度的洞察,因为它能清晰地揭示计算机何时处于不平衡状态。两种x86计算机的计算屋脊点分别为4.4和6.7——意味着访问DRAM的每个8字节操作数需要35到55次浮点运算——然而表4中16个核心与计算机组合的计算强度范围仅从0.25到1.64,中位数为0.60。如果架构师希望程序能在他们的新设计上达到峰值性能,就应该牢记屋脊点。
我们使用微基准测试来测量屋顶线和天花板,但我们也可以使用性能计数器(见附录A.1和A.3)。事实上,我们相信性能计数器和Roofline模型之间可能存在协同关系。自动创建Roofline模型的需求可以指导设计者在面对数百个候选指标但硬件预算有限时,应该收集哪些指标【6】。
我们相信Roofline模型可以为其他类型的多核系统(如向量处理器和GPU)、其他核心(如排序和光线追踪)、其他计算指标(如每秒成对排序次数和每秒帧数)以及其他流量指标(如L3缓存带宽和I/O带宽)提供洞察。我们邀请其他人加入我们,共同探索Roofline模型的有效性。
附录A可在CACM网站上在线找到:http://cacm.acm.org。