Debunking the 100X GPU vs. CPU myth: an evaluation of throughput computing on CPU and GPU
* Authors: Victor W. Lee, Changkyu Kim, Jatin Chhugani, Michael Deisher, Daehyun Kim, Anthony D. Nguyen, Nadathur Satish, Mikhail Smelyanskiy, Srinivas Chennupaty, Per Hammarlund, Ronak Singhal, Pradeep Dubey
- DOI: 10.1145/1815961.1816021
阅读内容总结
论文摘要(Abstract)
本文分析的计算对象是一组重要的吞吐量计算内核,这些内核中有足够的并行性足以适配多核CPU和GPU,过去(2010)一些年中GPU在这些计算内核上显示出持续上升的加速性能,从10X到1000X,本文揭示了巨大性能差距的原因;
进行了严密的性能分析,发现在为GPU和CPU都应用加速方法后,Nvdia GTX280和Core i7-960之间的性能差距平均只有2.5X。
讨论了关于CPU和GPU的加速技术,分析两种架构中引起不同的性能影响因素,提供了一组架构层面上显著提高吞吐率内核性能的因子
研究动机(Motivation/Introduction)
随着数据量快速的增长,吞吐量计算应用程序在合理的时间内向用户提供适当的内容至关重要。可以运行多种应用以及提供多核并行处理数据的CPU和设计由小运行部件进行图像处理的GPU是适用于吞吐量应用程序的两种主要平台。
本文试图将吞吐量计算特性与当今CPU和GPU的架构特性联系起来,并提供了为什么某些吞吐量计算内核在cpu上表现更好而其他内核在gpu上表现更好的见解。我们使用了一组内核和应用程序,这些内核和应用程序已经被先前的研究确定为吞吐量计算工作负载的重要组成部分。我们强调了特定于平台的软件优化的重要性,并推荐了一种应用驱动的设计方法,该方法可以根据应用程序特征识别基本的硬件架构特征。
CPU和GPU有不同的设计逻辑和适用场景:
- CPU设计目标是适于多种多样的应用和在单任务上提供快速响应。这种架构中的优势有分支预测,乱序执行以及超标量技术,为CPU提供高性能,但是这些独特的优势伴随着复杂度和空间占用提升以及能源消耗。因此,在能源和散热封装限制下,现在(2010)的CPU只能在单核中封装有限的处理单元。
- GPU面向诸如渲染之类的具有高数据并行的图形处理程序设计,因为显示器上的每一像素都可以独立处理。图形处理程序有延迟容忍性,因为只要帧以交互速率处理,每个像素的处理就可以延迟。因此,GPU可以为并行计算权衡单线程性能。例如,当遇到内存访问等长延迟事件时,GPU 可以从处理一个像素切换到另一个像素,并且可以稍后切换到前一个像素。当有足够的数据级并行性时,这种方法效果很好。GPU 上的应用程序加速最终受到串行部分的百分比的限制(根据 Amdahl 定律)。
CPU和GPU在吞吐量计算工作的问题:
- CPU为吞吐量计算工作负载提供最佳的单线程性能。但是,cpu中有限的核心数量限制了可以同时处理多少个数据。
- GPU 提供了许多并行处理单元,非常适合吞吐量计算。然而,图形管道的设计对于通用工作负载缺乏一些关键的处理能力(例如,大型缓存),这可能会导致吞吐量计算工作负载的体系结构效率较低。
本文主要的贡献如下:
- 复查了关于展示GPU比CPU快10X到1000X的研究。在为CPU和GPU都进行代码调优后,GPU只比CPU快2.5倍,这使得CPU和GPU在吞吐量计算方面的性能大致相同。
- 对吞吐量计算内核进行了系统的描述,包括可用的并行度、计算和带宽需求、访问模式和同步需求。确定了有效利用 CPU 和 GPU 平台的重要软件优化技术。
- 分析了CPU和GPU之间的性能差异,确定了有益于吞吐量计算负载的关键架构特征
文章脉络
第二节,讨论研究中适用的吞吐量计算;
第三节,描述两种主要的计算平台,CPU和GPU;
第四节,讨论选择的吞吐量计算在当前的计算平台上的性能
第五节,提供了一个平台定向化(platform-specific)的优化指导,提出了一组关键架构特征
第六节,讨论了相关工作;
第七节,总结了发现
符号系统(Notation)
结论(Conclusion)
- 分析了Core i7-960和GTX280上执行一组重要吞吐量计算内核的性能。
- 展示了CPU和GPU的性能差在2.5X,比之前研究中表现的数量级差异接近的多。
- 许多因素导致了性能上的巨大差异,例如使用的CPU和GPU,代码中使用的优化策略。
- CPU中影响性能提升的优化策略是:多线程,cache 分块以及SIMDification内存访问重组。GPU中影响性能提升的优化策略是:减小全局同步,使用本地共享缓冲。
- 对当前CPU和GPU的代码优化分析,找到了未来的吞吐量计算机器的关键的硬件架构特征:高计算带宽,大容量cache,分发和收集支持,高效的同步和修正过的计算单元
- 未来计划展示CPU和GPU能效研究。
主体工作
文章中使用的吞吐量计算
共利用了14种计算内核,采用的计算内核都有很大程度的数据集并行,令其能够自然的适配现代的多核架构。
根据 (1)计算和内存需求(2)内存访问的规律性(决定数据级并行的难易度)(3)任务的粒度(决定同步的影响程度) 对这些计算内核进行分类
细致描述如下:
- SGEMM
单精度矩阵乘法,包括稀疏矩阵和稠密矩阵,常规内存访问方式,特点是 O ( n 3 ) O(n^3) O(n3)的计算量和 O ( n 2 ) O(n^2) O(n2)的访存量,由于 O ( n ) O(n) O(n)的计算访存率使得SGEMM在适当阻塞下成为计算绑定的应用程序。
- MC
Monte Carlo(蒙特卡洛)随机采样一个复杂的函数,具有未知或高度复杂的分析表示,并平均结果。使用了计算金融学中的蒙特卡罗方法来进行期权定价。它模拟标的股票随时间的随机路径,并在时间步长结束时计算期权的收益。它多次重复这一步骤以收集大量样本,然后对这些样本进行平均以获得期权价格。蒙特卡罗算法通常是计算绑定的,具有规则的访问模式,这使得它非常适合SIMD体系结构
- Conv
卷积计算是一种常见的图像过滤操作,用于诸如模糊,浮雕和锐化等效果。它的数学计算主要是乘加操作,内存访问模式是在小间邻内的常规模式,每一个像素都可以独立处理,为SIMD和线程级并行提供了足够的并行性。
计算访存率随filter尺寸而变化,但是实践上常常可以获得高计算访存率。多维卷积不具备连续访问特性,因此要求好的cache blocking 操作
- FFT
快速傅里叶变换是信号处理中最重要的组成部分之一。它将信号从时域转换为频域,反之亦然。FFT( O ( n l o g n ) O(nlogn) O(nlogn)是实现离散傅立叶变换DFT( n 2 ) n^2) n2)的改进算法。尽管针对每种使用模型/硬件平台开发了各种优化,但它们的基本行为是相似的。它由 l o g n log n logn个阶段的蝴蝶计算和反向排列组成。算术计算是简单的浮点乘加,但数据访问模式并非平凡的伪全对全通信,这使得并行化和SIMD化变得困难。也关注在多核宽SIMD体系结构上实现FFT的挑战。
- SAXPY
BLAS库的基本操作,由标量乘法和向量加法构成,常规内存访问模式,很好的面向SIMD映射。线程级并行的使用只要求向量的很小一部分,对于无法放入one-die 存储中的长向量,SAXPY是一个带宽依赖的计算。对于短向量,SAXPY在垂直规约操作上占用大量时间。
- LBM
晶格玻尔兹曼方法,是计算流体动力学的一类。LBM使用离散玻尔兹曼方程来模拟牛顿流体的流动,而不是求解纳维·斯托克斯方程。在每个时间步中,对于D3Q19晶格,LBM遍历整个3D流体晶格,对于每个单元,从单元的19个邻居(包括自身)计算新的分布函数值。在每个时间步长内,可以以任何顺序遍历晶格,因为相邻的值是从前一个时间步长计算的。这一点使得LBM同时适用于TLP和DLP。LBM有O(n)个计算,需要O(n)个数据,其中是单元格的数量。工作集由单元及其19个相邻单元的数据组成。这些值的重用要比卷积少得多。大缓存不会显著提高性能。缺乏重用也意味着计算带宽比很低;LBM通常是带宽受限的。
- Solv
约束求解器是游戏物理模拟器的关键部分。在物理模拟管道执行期间,碰撞检测阶段计算碰撞体对,然后将其用作约束求解阶段的输入。约束求解器对这些对进行操作并计算分离接触力,使身体从互穿到另一个。约束通常分为一批独立的约束。SIMD 和 TLP 在独立约束之间都被利用。然而,由于为不同对象收集/散射对象数据(位置、速度)所需的聚集/散射操作的存在,利用SIMD并行性是具有挑战性的。理想情况下,约束求解器应该是带宽绑定的,因为它在给定的迭代中迭代所有约束,并且真实大规模破坏场景的约束数量超过了当今缓存的容量。然而,实际实现存在跨独立约束集的同步成本,这限制了当前架构的性能。
- SpMV
稀疏矩阵向量乘法是许多迭代求解器的核心,压缩行存储是最常用的稀疏矩阵存储格式,以这种格式进行计算的特点是基于列索引常规方式访问非零元以及向量上的不规则访问格式。当矩阵较大且不适合片上存储时,优化良好的内核通常是带宽界限。
- GJK
GJK(Gilbert–Johnson–Keerthi)算法是一种用于求解凸多边形之间的最小距离和检测它们是否相交的算法。GJK 的标量实现是当前 CPU 和 GPU 上的计算界限,并且可以利用 DLP 进一步加速运行时间。通过在不同的对象对上执行内核的多个实例来利用底层 SIMD。这需要将多个对象的对象数据(顶点/边)收集到SIMD寄存器中,以促进快速支持映射执行。因此,运行时依赖于底层硬件对有效收集指令的支持。还有一些技术可以通过将对象记忆到查找表来计算支持图,并在运行时对这些表执行查找。尽管仍然需要收集,但可以使用 GPU 上可用的纹理映射单元来执行此查找,以实现进一步的加速
- Sort
基数排序是许多领域中使用的多遍排序算法,包括数据库。每次传递一次对输入的一位数字进行排序,至少是最重要的。每一次传递都涉及以记忆分散的形式进行数据重排。在 CPU 上,最好的实现放弃了 SIMD 的使用,并在缓存中实现了面向散射的重排。在 SIMD 使用很重要的 GPU 上,该算法使用称为拆分 的 1 位排序原语重写。然而,基于拆分的代码比缓冲区代码具有更多的标量操作(因为它一次在单个位上工作)。因此,即使对于拆分代码,SIMD 相对于优化标量代码的整体效率也不高。基数排序每遍考虑的比特数取决于本地存储的大小。因此,增加缓存大小会提高性能(缓存大小的每倍都会增加一次的比特数)。总体而言,基数排序具有 O(n) 带宽和计算需求(其中 n 是要排序的元素的数量),但由于 SIMD 使用效率低下,通常计算界限。
- RC
Ray Casting(光线投射)是一个重要的视觉应用,用于可视化 3D 数据集,例如医学成像中使用的 CT 数据。高质量的算法,称为光线投射,通过体积投射光线,根据体素不透明度和颜色将每个体素合成到相应的像素中。使用SIMD跟踪多条光线是具有挑战性的,因为光线可以访问不连续的内存位置,从而导致不连贯和不规则的内存访问。一些光线投射实现执行大量的计算,例如梯度阴影。由于访问相同体积数据的相邻光线而导致的第一级工作集相当小。然而,最后一层工作集可以与体积本身一样大,这是几 GB 的数据。
- Search
搜索或内存内树结构索引搜索是计算机科学各个领域中常用的操作,尤其是数据库。对于 CPU,性能取决于树是否适合缓存。对于小树(小于最后一层缓存 (LLC) 的树大小),搜索操作是计算绑定的,并且可以利用底层 SIMD 来实现加速。然而,对于大树(大于 LLC 的树大小),树的最后几层不适合 LLC,因此搜索的运行时间受可用内存带宽的限制。就 GPU 而言,即使对于大型树,可用的高带宽也超过了所需的带宽,运行时间是计算界限。
- Hist
直方图计算是一种重要的图像处理算法,它将连续数据流中的像素散列和聚合到更少的二进制数中。虽然地址计算是 SIMD 友好的,但聚合的 SIMDification 需要硬件支持进行冲突检测,目前在现代架构中不可用。访问模式是不规则的,因此SIMD很难利用。通常,直方图的多线程需要原子操作支持。然而,直方图有几种使用私有化的并行实现。通常,可以对私有直方图进行拟合,以适应可用的片上存储。然而,减少私有直方图的开销很高,这成为高度并行架构的主要瓶颈。
- Bilat
双边滤波器是图像处理中常用的非线性滤波器,用于边缘保持平滑操作。核心计算结合了空间滤波器和强度滤波器。相邻像素值和位置用于计算新的像素值。它具有很高的计算需求,性能应该随着触发器的增加而线性扩展。典型的图像大小很大; TLP/DLP 可以通过划分线程和 SIMD 单元之间的像素来利用。此外,双边滤波器涉及计算指数等超越运算,这可以极大地受益于快速数学单元。
高性能计算平台介绍
基于Intel Core i7-960的CPU计算平台和基于Nvdia GTX280 的GPU计算平台
下图是两种平台的主要参数和峰值性能比较
两种架构的细节
- Intel Core i7-960
最新(2010)的Intel多核多线程处理器,具备乱序超标量微架构,具有4宽度的SIMD单元。
主频3.2GHz,4核,两路超线程,每个核心有32KB的数据L1和指令L1和一个256KB的L2 数据cache,4核共享8MB的L3 数据cache。
具备片内内存控制,可以连接三通道的DDR主存
- Nvidia GTX280
由一系列多处理器组成(即SM)。每个 SM 有 8 个标量处理单元,每个单元以固定频率1.3 GHz 工作。硬件SIMD结构通过线程扭曲提供给程序员。为了隐藏内存延迟,GTX280提供硬件多线程支持,允许数百个线程上下文同时处于活动状态。为了减轻内存带宽,该卡包括各种片上存储器——例如多端口软件控制的16KB存储器(称为本地共享缓冲区)和小型非相干只读缓存。GTX280还具有特殊的功能单元,如纹理采样单元和用于快速超越操作的数学单元。
吞吐量计算程序的实现
分别描述两种架构之间不同的硬件细节特征,和它们对吞吐量计算程序的实现
- 处理单元的不同
CPU每个内核都支持标量和SIMD操作,而且支持多发射和分支预测,因此限制了片内封装核的数目;GPU每个 SM 相对简单。它由一个获取单元和八个标量单元组成。每条指令在 32 个数据元素的四个周期中在所有八个标量单元上并行获取和执行(即经纱)。这使每个 SM 的面积相对较小,因此与 CPU 内核的数量相比,每个 die 可以打包更多的 SM。
- cache大小和多线程
CPU利用cache来保存和预取常用数据;相比之下,GPU 提供了大量轻量级线程来隐藏内存延迟。每个 SM 可以支持每个多处理器多达 32 个并发warp。由于warp中的所有线程执行相同的指令,因此在发出内存请求时会关闭warp。为了捕获对同一数据的重复访问模式,GTX280 提供了一些本地存储(共享缓冲区、常量缓存和纹理缓存)。
- 带宽差距
Core i7 提供了 32 GB/sec 的峰值外部存储器带宽,而 GTX280 提供了大约 141 GB/sec 的带宽。尽管峰值带宽的比率非常大(~4.7X),但对于不使用 SFU 中的融合乘法加法的应用程序,每个触发器的字节比率相对较小(~1.6X)。
- 其他不同
CPU 为快速同步操作提供,这在 GPU 上不能有效地实现。CPU还为高效的寄存器内跨车道SIMD操作提供,如一般的shuffle和swizzle指令。另一方面,通过将数据存储到共享缓冲区中,并在 GPU 上模拟此类操作,并使用适当的 shuffle 模式对其进行加载。这给一些吞吐量计算应用程序带来了巨大的开销。相比之下,GPU 支持从内存中收集/分散指令,这在 CPU 上并未有效实现。Gather/Scatter 操作对于需要访问要以 SIMD 方式操作的非连续内存区域的应用程序增加 SIMD 利用率很重要。此外,纹理采样单元和数学单元等特殊功能单元的可用性,以实现快速超越,有助于加速在这些操作中花费大量时间的吞吐量计算应用程序。
CORE I7和GTX280的性能评估
基本方法与实验结果
操作系统:the SUSE Enterprise Server 11 operating system
CPU:6GB 1333 DDR3内存,Intel DX58SO主板
GPU:eVGA GeForce GTX280,1G显存,Nvidia driver version 19.180 and the CUDA 2.3 toolkit.
由于只对在芯片级别比较 CPU 和 GPU 架构,以查看任何特定的架构特征是否负责性能差异感兴趣,因此我们没有包括 GPU 测量的数据传输时间。我们假设吞吐量计算内核在其他计算的中间执行,这些计算在内核执行之前在 GPU 内存中创建数据,并使用内核在 GPU 内存中生成的数据。对于不满足我们的假设的应用程序,传输时间会显着降低 Datta 报告的性能。此处介绍的 GPU 结果是这些算法实际应用中看到的上限。
对于 CPU 和 GPU 性能测量,我们为每个平台单独优化了大部分内核。对于一些内核,我们使用了已经存在的最佳可用实现。具体来说,SGEMM、SpMV、FFT 和 MC 在 GTX280 上的评估是使用图 1 中的代码完成的:Core i7 和 GTX280 性能比较。。对于 Core i7 上的 SGEMM、SpMV 和 FFT 的评估,我们使用了 Intel MKL 10.0。
表 3 显示了 Core i7 和 GTX280 处理器上吞吐量计算内核的性能,并具有标题中显示的适当性能指标。据我们所知,我们的性能数字至少与最佳发布数据相当,并且通常优于最佳发布数据。我们通常发现,当每个核心使用多个线程时,性能最高。对于 Core i7,最佳性能来自于在 4 个内核上运行 8 个线程。对于 GTX280,虽然可以在一个 GPU SM 上执行的最大wrap数为 32,但需要明智的选择来平衡多线程的好处,并增加寄存器和片上内存资源的压力。内核通常以每个核心 4 到 8 个wrap运行,以获得最佳的 GPU 性能。
实验结果比较
展示的是GTX 280与Core i7的性能比较倍数。
数据表明,在测试的 14 个内核中,GTX280 的平均性能仅比 Core i7 高 2.5 倍。由于使用纹理采样器,只有GJK内核 实现了超过 10X 的性能差距。Sort和 Solv 在 Core i7 上实际上表现更好。实验结果远远少于以前的主张,如MC[9]、LBM[45]的114X差异、FFT[21]的40X差异、SpMV[47]的50X差异和Hist[53]的40X差异等。有许多因素促成了先前报告的结果和我们的结果之间的巨大差异。一个因素是比较中使用了 CPU 和 GPU。将高性能 GPU 与移动 CPU 进行比较并不是最佳比较,因为它们对工作功率、热包络和可靠性的考虑完全不同。另一个因素是在 CPU 和 GPU 上执行了多少优化。许多研究将优化的 GPU 代码与未优化的 CPU 代码进行比较,并产生了很大的差异。其他研究对 CPU 和 GPU 执行仔细优化,例如 [27, 39, 40, 43, 49] 报告了与我们类似的低得多的加速。
性能的分析
分析了性能结果并识别有助于我们每个内核性能的架构特征。首先确定纯粹基于两个基本处理器资源之一的内核——带宽和计算。然后,确定了其他架构特征的作用,例如用于不规则内存访问的硬件支持、快速同步和硬件来执行固定函数计算(例如纹理和超越数学操作)以加速剩余的内核。
-
带宽
实验使用的14种内核都需要额外的内存带宽来把数据送到处理单元。
内存带宽的影响取决于两个因素:1.kernel是否有足够的计算量来完全的利用内存访问;2. kernel是否有能放入片内存储的工作集。
- SAXPY和LBM内核的工作集都依赖于全局内存访问而不依靠已加载的数据,因而它们是完全的带宽依赖内核,可以从带宽增长中获益。实验中两种计算的比例是5.3X和5.0X和峰值带宽比值4.7X十分接近。
- SpMV有大工作集和少量的计算,然而性能比只有1.9X,比峰值带宽比例低了2.3倍。这是因为在具体实现时,GTX280把向量和列数据结构都保存在显存中,因为无法放入小的片载共享缓冲,但是i7可以把一半矩阵的向量和列数据都保存在cache中,因此GPU平均比CPU多2.5倍的带宽需求。
其他内核要么具有较高的计算带宽比,要么在片上存储中完全或部分拟合工作集,从而减少内存带宽对性能的影响。这些类别的核将在后面的部分中描述。
-
浮点计算
由于多核的存在,处理器上可用的计算取决于单线程性能,以及由于宽向量(SIMD)单元而存在的TLP。虽然大多数应用程序(带宽绑定内核除外)可以通过利用额外的内核从改进的单线程性能和线程级并行性中受益,但并非所有内核都可以很好地利用 SIMD。
确定了 SGEMM、MC、Conv、FFT 和 Bilat能够在 CPU 和 GPU 架构上利用所有可用的计算。
SGEMM、Conv 和 FFT 在 2.8-4X 范围内具有 GTX280 到核心 i7 性能比率。这接近于 GTX280 与 Core i7 架构(见表 2)的 3-6X 单精度 (SP) 触发器比,具体取决于内核是否可以利用融合的乘加。
没有达到峰值计算比率的原因是GPU在存在共享缓冲区访问时没有达到峰值效率。Volkov等人表明,即使对于SGEMM(已知是计算界),GPU也只能获得约66%的峰值flop。我们的结果符合他们的业绩比率。MC使用双精度算法,因此具有1.8X的性能比,接近1.5X的双精度(DP)比。Bilat利用gpu的快速超越运算(后面会介绍),GTX280与Core i7的性能比优于5倍。Sort使用的算法严重依赖于处理器的SIMD宽度。典型的基数排序实现涉及对数据重新排序,其中涉及缓冲区管理和数据分散的许多标量操作。然而,标量代码在GPU上是低效的,因此最好的GPU排序代码使用SIMD友好的分割原语。这比标量代码有更多的操作-因此在GTX280上比在Core i7上慢1.25倍。
-
Cache
如带宽一节所说,当工作集可以完全适配入cache的计算限制内核,性能会随着计算的增加而扩展,我们确定为计算绑定的五个内核具有可以调优以适应任何合理大小的缓存的工作集,而不会造成显著的性能损失。因此,它们只依赖于某种片上存储的存在,并且计算绑定在cpu和gpu上。有些内核的工作集无法在不损失性能的情况下轻松调优到任何给定的缓存大小。基数排序就是一个例子,它需要一个随着每次排序所考虑的比特数而增加的工作集。
决定内核性能的另一个重要工作集特征是,工作集是随着线程数量的增加而增加,还是由所有线程共享。像SGEMM、MC、Conv、FFT、Sort、RC和Hist这样的内核都有工作集,这些工作集随线程数量的变化而变化。这些内核需要比cpu更大的gpu工作集(线程更多)。如果内核可以平装到任意大小的缓存(例如SGEMM和FFT)中,这可能不会对性能产生任何影响。然而,平铺只能在一定程度上用于RC。因此,RC在gpu上成为带宽绑定,gpu的片上存储非常少,但在cpu上没有带宽绑定(而是受到汇聚/散射的影响,后面会介绍),GTX280与Core i7的性能比仅为1.6X,远低于带宽和计算比。
-
收集/分发
没有带宽界限的核可以通过增加 DLP 中受益。然而,SIMD 执行单元的使用对内核实现施加了限制,尤其是在数据的布局中。SIMD操作的Operands和结果通常需要在内存中按顺序组合在一起。为了实现最佳性能,应将它们放入地址对齐结构中(例如,对于 4 宽的单精度 SIMD,最佳性能将是数据为 16 字节对齐时)。如果数据不满足这些布局限制,程序员必须转换内核的数据布局。这通常涉及收集/分散操作,其中操作数从多个位置收集并打包成一个紧密的分组,结果分散到多个位置。在软件中执行聚集/散射可能很昂贵。3 因此,有效的硬件支持来收集/分散操作是非常重要的。
在 Core i7 上,没有硬件收集/分散支持。因此,GJK 和 RC 不能有效地利用 SIMD。例如,由于软件收集的开销很大,RC 从 0.8X 和 1.2X 之间的 SSE 看到了非常增量的好处。GJK 也看到了 SSE 的最小好处。在 GTX280 上,提供对本地缓冲区和 GDDR 内存的访问的支持。本地共享缓冲区支持对多个银行同时收集/分散访问。GDDR内存控制器将请求合并到同一行,以减少收集/分散访问的数量。这种改进的聚集/散射支持导致 GJK 在 GTX280 上的性能相对于 Core i7 的改进。然而,聚集/散射支持对 RC 性能的影响很小(1.2X),因为访问广泛分布到内存中,即使合并支持,也需要多个 GDDR 访问——因此它受到 GPU 内存带宽的限制。因此,GTX280 与 RC Core i7 性能的比率仅为 1.6X,略好于 1.5X 的标量触发器比率。
-
归约与同步
吞吐量计算内核通过线程级(多个内核和线程)和/或数据级(宽矢量)并行性实现高性能。缩减和同步这两个操作不会随着线程数和数据级并行性的增加而扩展。
Hist 的性能主要受原子更新的限制。尽管 Core i7 支持硬件锁增量指令,但 28% 的总运行时间仍然花在原子更新上。GTX280 上的原子更新支持也非常有限。因此,为 CPU 和 GPU 实现了每个线程生成局部直方图的私有化方法。然而,这种实现并没有随着核心计数的增加而增加,因为减少开销随着核心数量的增加而增加。此外,缺乏跨SIMD pass操作,如gpu上的归约,会导致GTX280上的指令开销很大。因此,Hist在GTX280上比Core i7快1.8倍,远低于计算和带宽比(约5倍)。
Solv中,一批独立的约束由多个核心/线程同时执行,然后在执行下一个批处理之前执行障碍。由于解决约束只需要少量的计算(按照几百条指令的顺序),因此任务粒度很小。因此,执行时间以屏障开销为主。在 Core i7 上,障碍是使用原子指令实现的。虽然可以完全在 GPU 上实现障碍操作,但此实现并不能保证先前对所有内存层次结构级别的访问已经完成。CPU 在缓存一致性协议的帮助下提供了一个内存一致性模型。由于缓存一致性在当今的 GPU 上不可用,因此在两批约束之间确保内存一致性需要从 CPU 主机启动第二批,这会导致额外的开销。因此,与约束求解器的 Core i7 相比,GTX280 的势垒执行时间比 Core i7 慢一个数量级,导致 GTX280 的性能总体下降 1.9 倍。
-
固定功能
Bilat 由计算指数函数和幂函数等超越操作组成。然而,出于图像处理目的,这些功能的高精度版本是不必要的。当前的 CPU 使用代数表达式来评估此类表达式,直到所需的精度,而现代 GPU 提供硬件来加速计算。在 Core i7 上,大部分运行时间(大约 66%)用于超越计算。在 GTX280 上,由于存在快速超越硬件,与 Core i7 相比,它实现了 5.7 倍的性能比(超过大约 3X 的峰值计算比)。在 Core i7 上加速超越(例如,如在 GTX280 上)将将将 Bilat 性能提高大约 2X,由此产生的 GPU 到 CPU 的性能比约为 3X,更接近峰值计算比。
MC 是另一个内核,可以从 CPU 上的快速超越中受益。现代 GPU 还为其他固定函数单元提供,例如纹理采样单元,这是渲染算法的主要组成部分。然而,通过将线性时间支持图计算减少到恒定时间纹理查找,GJK碰撞检测算法可以利用GPU的快速纹理查找能力,在Core i7上,GTX280上的加速比总体为14.9倍。
优化方向讨论
特定于平台的软件优化对于完全使用 CPU 和 GPU 的计算/带宽资源至关重要。我们首先讨论这些软件优化技术,并推导出许多关键硬件架构特征,这些特征在提高吞吐量计算工作负载的性能方面起着重要作用。
面向软件优化指导
传统上,CPU 程序员严重依赖增加时钟频率来提高性能,并且没有优化它们的应用程序以完全提取 TLP 和 DLP。然而,CPU 正在演变以包含更多具有更广泛 SIMD 单元的内核,并且并行化以利用 TLP 和 DLP 的应用程序至关重要。在没有此类优化的情况下,CPU 实现在性能上是次优的,并且可以比它们可达到的性能低几个数量级。
例如,先前报告的 GPU 上的 LBM 数字声称 CPU [45] 上的 LBM 速度提高了 114 倍。然而,我们发现,通过仔细的多线程、内存访问模式的重组和SIMD优化,cpu和gpu的性能都受到内存带宽的限制,差距减少到只有5X。
现在我们重点介绍我们从优化吞吐量计算内核中学习到的关键平台特定优化技术。
- CPU优化方法
- 大多数内核可以与内核的数量线性扩展。因此,多线程在 Core i7 上提供了 3-4 倍的性能改进。
- CPU 严重依赖缓存来隐藏内存延迟。此外,与 GPU 相比,CPU 上的内存带宽较低。阻塞是一种减少 CPU 上 LLC 未命中的技术。程序员必须知道底层缓存层次结构或使用自动调优技术来获得性能最好的内核。许多内核,SGEMM、FFT、SpMV、Sort、Search 和 RC 使用缓存阻塞。Sort,为了获得最佳性能,需要调整每遍的位数,以便其工作集适合缓存。RC 阻塞体积以增加束中光线之间的 3D 局部性。我们观察到缓存阻塞将 Sort 和 Search 的性能提高了 3-5 倍。
- 重新排序数据以防止不规则内存访问对于 CPU 上的 SIMD 利用率至关重要。主要原因是 CPU 没有收集/分散支持。Sort执行显式SIMD阻塞,使内存访问规则。Solv 对约束进行重新排序以提高内存访问模式。其他内核,例如 LBM 和 RC,将一些数据结构从结构数组转换为数组结构格式,以完全消除收集操作。例如,LBM 的性能从这个优化提高了 1.5 倍。
- GPU优化方法
- 最小化全局同步,全局线程间同步非常昂贵,因为它涉及主机的内核终止和新的内核调用开销。Hist 通过私有直方图来最小化全局同步。Solv 还执行约束重新排序以最小化相邻约束之间的冲突,即全局同步点。
- 使用本地共享缓冲区。我们的大多数内核使用共享缓冲区来减少带宽消耗。
硬件指导
利用之前的性能评估来导出许多关键处理器特征,这些特征在提高吞吐量计算应用程序性能方面发挥了重要作用。
- 提高计算性能和内存带宽
- 增加cache大小
- 收集和分发支持
- 高效的同步和缓存一致性
- 固定功能部件