论文部分内容阅读
伴随能在GPU上高效执行的应用类型的不断增加,原来作为专业化的图形加速器变得越来越通用化。作为科学计算的一种形式模板计算应用也可移植到GPU中并能充分利用其不同类型的存储器资源获得显著的加速。模板计算利用循环空间某被计算点的邻域不断更新该点的值,同时最外层循环通常与物理时间相关,在每个计算的物理时间点,内环高维数组定义为邻域高维数组的函数。目前不同类型的模板广泛用于计算电磁学、偏微分求解以及CT或MRI成像中,甚至大量地用来对湍流、地震波传播等进行物理仿真的加速。从事这些应用研究的专家无法详尽地运用GPU的体系结构特征对代码进行性能的优化,因此为了取得更高层次的底层性能优化和更好的可移植性,研究和设计基于GPU模板计算的特定域语言和不断优化模板计算代码有重要意义。本文将针对面向大规模计算的GPU系统中如何设计能产生高效的模板代码的特定域语言以及存储带宽的优化面临的各种挑战,研究相应的代码生成模板规范、算法和基于体系结构特征的优化,并实现相关的编译器流程和模板代码的优化。本文的贡献主要包括以下方面:(1)模板规范和模板编译流程。采用抽象语法规则定义的模板规范为特定体系结构的自动代码产生提供了基础,手写的模板规范或模板编译器从高级语言编写的模板程序中抽取的规范作为模板编译流程的输入而产生新的中间表示,该中间表示用抽象的语法树结构来呈现模板程序的所有域及其对应的模板函数,每个域中定义了其数据类型和其可读或写的语义,对于多个模板函数遵循顺序执行的语义。(2)自动生成带重叠ghost zone的CUDA或Open CL代码。用循环分块本地线程的冗余计算代替不同循环分块在模板计算时的通信,既充分发挥了GPU强大的计算能力也大量地降低了线程簇warps或threads group之间的通信开销。产生代码时利用主机代码生成算法和GPU代码生成算法产生主机代码和相邻循环分块边缘彼此重叠的GPU代码。为了使产生的代码能高效执行,在代码产生过程中需要执行线程块大小确定算法和共享存储器的分配算法。(3)消除了在加载循环分块边缘重叠区的条件语句带来的控制流分歧。通常GPU以32(Nvidia)或64(AMD)个线程构成的线程簇warps或threads group同时执行,然而如果代码中存在条件语句,这些线程因存在控制流分歧而不能同步执行,这样带来大量的线程不同步开销。通过设计新的模板数据载入共享存储器的算法,上述的控制流分歧可以完全消除。(4)采用不同的策略优化了模板计算所大量需要的存储器带宽资源。GPU的全局存储器访问采用对齐的32个字节合并的方式访问降低了带宽需求;线程的执行同时利用共享存储器空间和寄存器,适当加载模板格点数据和中间临时数据到寄存器,有利于启动更多的线程执行,增大了线程执行的并行粒度;本文设计的软件预取机制在模板计算的前后迭代循环更新模板点值时需要相邻模板XY-平面的数据,当前迭代循环加载的数据被紧接着的迭代循环作为计算模板点更新值的输入,在GPU的warp调度或threads group调度的基础之上进一步重叠了算术操作与存储器访问的延迟。