论文部分内容阅读
GPU的浮点峰值、访存带宽以及性能功耗比都超出同时代的CPU若干倍,成为加速计算密集型应用的引擎。然而,实际GPU程序的性能却远低于GPU的浮点峰值。比如,经过深度优化的稠密矩阵乘算法和卷积算法的CUDA实现在Kepler GPU上的浮点运算效率仍然都低于50%。综合分析相关工作和观察反汇编程序,本文发现CUDA编译器NVCC的代码生成存在一些性能问题。比如,编译器的寄存器分配存在寄存器bank冲突,编译器生成的控制码不能充分利用FFMA双发射等,这些因素导致GPU的资源不能被充分利用。这些因素在CUDA这种高级语言是无法解决的和改善的,只能在汇编层次上才能解决。但是多年来,由于NVIDIA厂商封闭惯性,只为GPU编程人员提供了CUDA和PTX编程模型,并未公开其汇编器。其内部工作人员使用汇编器优化少量的算法,而大部分的算法不能合理利用GPU微处理器的资源。 本文围绕NVCC生成代码效率低、Kepler GPU无可用汇编器和GPU指令编码未公开等问题,提出了一个方法(PerfFlow)来解决当前的困境:通过设计指令解码器得到指令编码,并基于破解后的指令构造汇编器;然后,设计汇编探测程序探测GPU的微架构特点,并把GPU微体系结构特点与性能关联起来;最后使用探测出的架构特性优化实际算法。由于稠密矩阵乘是线性代数库和近几年来兴起的深度学习应用的核心运算,是检验体系结构研究最直接有效的基准测试程序,本文以单精度矩阵乘算法(SinglePrecision General Matrix Multiply,简称SGEMM)为例展示了面向GPU微体系结构的算法优化。 本文的主要工作包括: 本文通过观察GPU ISA(Instruction Set Architecture)编码特点,提出基于反汇编器的操作码、修饰码和操作数编码的求解器InstSolver。该求解器可以自动求解任意64位定长的NVIDIAGPU架构的编码,只需要输入相应的反汇编代码即可。 在获取Kepler指令编码的基础上,本文实现了Kepler GPU的开源汇编器KeplerAs。基于汇编器的解决方案可以作为NVCC的补充,打破NVIDIA的封闭开发环境,为深度探测GPU的微架构和汇编优化提供了可能。 本文基于GPU汇编语言设计并标准化微基准测试程序(Bare-Metal-Microbenchmarks),并探测出微体结构的特性:如寄存器bank分布、双发射模式、指令通量和延迟、不同位宽的访存指令对于共享内存和全局访存带宽的影响。 根据GPU微体系结构特点,本文以SGEMM为例介绍了如何面向微体系结构的特征对算法进行深度优化。这些优化策略贯穿整个GPU架构,从寄存器bank、 CUDA核的双发射到共享内存和全局内存访存,再到指令调度。SGEMM的最终性能达到88%的效率,比cuBLAS快15%,其中双发射指令提升性能约一倍。同样的方法应用于卷积算法,卷积算法相对cuDNN提升了一倍左右,展示优化方法的通用性。汇编优化的kernel使得整体的卷积神经网络相对与NVIDIA的实现提升78%。本文建立了SGEMM在GPU上的Roofline性能分析模型,分析SGEMM的上界和性能瓶颈。本文的优化经验可以指导更多算法优化以及编译器的代码生成优化。