高性能GPU模拟器的实现①

2020-07-16 08:58:52张立志赵士彭赵皓宇苏孟豪
高技术通讯 2020年6期
关键词:模拟器光栅流水

张立志 赵士彭 赵皓宇 苏孟豪* 刘 苏*

(*计算机体系结构国家重点实验室(中国科学院计算技术研究所) 北京 100190)(**中国科学院计算技术研究所 北京 100190)(***中国科学院大学 北京 100049)(****中国科学技术大学计算机科学与技术学院 合肥 230026)(*****龙芯中科技术有限公司 北京 100190)

0 引 言

图形处理器(graphics processing unit,GPU)是计算机系统中处理3D实时图形程序的专用加速芯片,目前广泛应用于个人电脑、工作站、嵌入式设备与智能手机中。在中央处理器(central processing unit,CPU)与GPU的芯片设计[1]中,当对某款处理器进行结构探索时,通常并不是直接使用硬件描述语言对芯片进行实现与验证,而是使用高级语言(如C、C++)编写对应的处理器模拟器,来进行结构探索与功能验证,因为高级语言编写的模拟器在功能实现与错误调试方面都更为简单快捷,同时可以对结构进行低成本的优化改进。

在GPU的架构演进[2,3]中,GPU的功能不断增多。1992年美国硅图公司将图形流水线应用于GPU[4],GPU的原始输入数据是由CPU预先处理好的三角形数据,GPU只负责光栅化与纹理采样等少数几个操作,功能非常单一。在不断的发展过程中,GPU逐渐开始负责原本由CPU负责的三角形的生成与剔除、顶点光照特效、顶点数据移动变换操作、像素点特效操作、曲面细分等功能。越来越复杂的GPU功能使得进行直接芯片实现的成本巨大,故模拟器验证变得越来越重要。随着GPU功能的丰富与性能的提升,GPU结构变得越来越复杂,GPU模拟器的代码规模也越来越庞大,灵活性越来越低,这使得GPU模拟器不易添加新的功能模块,也增加了测试验证的难度。

为解决周期精确模拟器GPU模拟器代码灵活度低的问题,本文提出并实现了一种半周期精确的GPU模拟器实现方法,基于该方法设计的GPU模拟器可以快速地对3D图形算法进行正确性验证与性能分析。

本文的主要贡献是:(1)结合GPU结构特性,提出了半周期精确的GPU模拟器设计方法。该方法在保证功能验证与性能评估的基础上,降低了GPU模拟器内部功能模块之间的耦合度,增加了模拟器灵活性,同时降低了GPU模拟器使用者对模拟器的学习成本。它将GPU固定功能管线部分使用逆序流水方式实现完全的周期精确模拟,在可编程流处理器单元使用单周期处理器的功能模拟,各模块之间使用队列对周期精确进行解耦合。(2)将半周期精确模拟器设计方法应用于实际系统,实现一款GPU模拟器,并使用glmark2测试集对该模拟器进行功能正确性验证,同时对三角形光栅化算法进行了性能评估。

1 相关工作

现代GPU架构主要由2部分构成,即固定功能管线与可编程流处理器单元。固定功能管线主要负责GPU中图形算法的实现与GPU内各模块的调度;可编程流处理器单元负责执行图形程序中的顶点着色器与片段着色器代码,同时因为其可编程特性,近些年较为火热的GPGPU[5](general-purpose computing on graphics processing unit)也由可编程流处理器单元实现。

目前国内外已经提出多种高级语言编写的GPU模拟器,这些模拟器也可依据GPU架构的特性分为2类:完整的GPU模拟器和只实现可编程流处理器单元的通用计算模拟器。其中通用计算模拟器涵盖了近些年大部分GPU模拟器,例如Multi2Sim[6]、Multi2Sim Kepler[7]、MIAOW[8]、GPGPU-Sim[9]与基于Gem5 CPU模拟器[10]开发的gem5-gpu[11]。这些模拟器只对可编程流处理器单元进行模拟仿真,可以运行完整的GPGPU程序,但不包含引言所提到的光栅化与纹理采样操作、三角形的生成与剔除、顶点光照特效、顶点数据移动变换操作、像素点特效操作、曲面细分等功能,无法执行任何完整的图形应用程序。

因为GPU技术中图形处理技术主要掌握在少数商业GPU厂商手中(如Nvidia、AMD),他们因为商业原因,并没有将GPU技术对外公开,所以学术界所使用的GPU模拟器数目并不多。所公开源代码的GPU模拟器中最具代表性且广泛使用的模拟器是ATTILA模拟器[12]。ATTILA模拟器是加泰罗尼亚理工大学于2006年与Intel公司共同开发的一款完全周期精确的GPU模拟器,模拟器一直维护至2015年。该模拟器为了实现完全的周期精确模拟,使用Signal数据结构详细模拟了Verilog HDL语言中的Wire,同时模拟了时序延迟与传输带宽。这种处理方式虽然保证了模拟器的正确性与准确度,但是极大增加了模拟器的软件规模与软件结构复杂度,使得开发者难以在模拟器上增加新的功能模块,更加难以对所模拟的GPU结构进行较大规模的升级修改。在图形算法的模拟中,ATTILA采用时序模拟与算法功能仿真分离的实现方式,分别使用不同的模块进行实现,这种方法再次增加了代码的可调试性与阅读难度。加泰罗尼亚理工大学于2013年再次与Intel公司合作开发了Teapot[13]模拟器,迄今一直在维护使用,但该模拟器依然采用了完全周期精确的模拟方式,没有解决模拟器的灵活性问题。

为解决GPU模拟器软件结构过于复杂且不易进行结构更改与代码调试的问题,同时结合前述模拟器实现方法与GPU本身特性,本文提出了半周期精确的GPU模拟器实现方法,该方法在保证功能正确的基础上,降低了GPU模拟器软件结构复杂度,使得模拟器使用者可以快速地为GPU模拟器添加新功能,并使用OpenGL 2.0程序为该功能模块进行正确性验证与性能分析。

2 半周期精确模拟器

在完整的GPU设计路线中,模拟器只是一个阶段性产物,而不是像ATTILA模拟器与Teapot模拟器在其项目规划中将模拟器作为最终产物,简单高效的实现模拟器将极大影响GPU的整体研发效率。半周期精确模拟器的设计目的是在GPU结构设计初期对结构进行功能正确性验证与性能分析。由于GPU最终结构设计代码将由Verilog HDL语言编写,用高级语言编写的模拟器在功能与结构上与最终所期待GPU有很大差距。所以在使用模拟器对GPU结构进行验证后,还需要使用现场可编程门阵列(field progrmmable gate array, FPGA)进行更深一步验证与性能评估。

GPU一般由固定功能管线与可编程流处理器单元2部分构成。固定功能管线是一条数据驱动的图形算法流水线电路,驱动数据为顶点数据与像素点数据;可编程流处理器单元则是指令驱动处理器,可进行取指、译码、执行、访存操作,其指令为着色器程序的汇编指令。这2个面向不同处理对象的单元由先入先出 (first input first output,FIFO)或随机存取存储器(random access memory,RAM)进行解耦合。在进行性能评估时[14,15],固定功能单元性能指标一般为每秒或每周期可处理的顶点数目与像素点数目;而可编程流处理器单元性能指标一般为每秒可处理浮点指令的数目。这是因为在实际3D图形应用中,即使使用相同的顶点数据与像素点数据,在调用不同着色器程序时,图形的显示效果也大不相同。一般增加着色器程序指令数目后,图形显示效果将更加逼真细腻,同时可编程流处理器单元执行的时间也将变长,进而影响到固定功能单元每秒可处理的顶点数目与像素点数目。这2个单元在性能评估阶段并没有使用相同的标准,而且这2个性能评估标准也无法进行进一步的统一衡量。

基于上述原因,本文基于“GPU由固定功能单元与可编程流处理器单元共同组成”这一特性,将GPU模拟器实现为半周期精确的功能级模拟器。将固定功能管线进行周期精确的模拟,所有模块在模拟器中所执行时间与该模块在真实芯片中执行时间相同,例如32位乘法部件将进行4个时钟周期的全流水模拟,与真实芯片执行时间相同。而可编程流处理器单元则不进行周期精确的模拟,只进行指令级功能模拟,每周期处理一条完整指令。虽然在真实芯片中,每条指令将进行多周期全流水执行,但单周期功能级模拟也将满足程序正确性,并且极大降低了模拟器平台调试与更改的复杂度,同时节省了开发成本。不同于ATTILA模拟器,本文在对模拟器实现时,使用倒序流水与虚假执行的方式将功能模拟与时序模拟实现在同一模块,增加了代码的可读性与可调试性。

3 模拟器实现

GPU模拟器主要由3部分构成,分别是模拟器驱动程序、GPU固定功能单元和GPU可编程流处理器单元。其中GPU固定功能单元还包括光栅化单元。下面将依次对这些模块进行介绍。

3.1 GPU模拟器驱动程序

为了快速方便地为GPU模拟器生成输入数据,GPU模拟器配套开发一套基于Mesa[16]驱动程序的模拟器驱动程序。模拟器驱动程序可适配OpenGL等多款应用程序接口,可以将正在运行的OpenGL程序的信息抓取出来。所抓取信息包括顶点数据、纹理数据、OpenGL流水线状态、GPU命令、着色器代码。这些数据将作为GPU模拟器的输入数据。

3.2 模拟器具体实现

模拟器整体软件架构主要由Module和Queue 2个数据结构与Clock函数构成。Module用于构建GPU中每一个功能单元,类似于Verilog HDL语言中关键词module。Queue用于实现各个Module间通讯功能,同时实现各Module的解耦合。Queue在本质上是一个每周期一写一读的循环队列。具体实现方式如图1所示。其中方框表示Module,对应GPU中每一个部件。每个Module都具有自己的Clock函数,该函数实现了对应模块在每个时钟周期内应当执行的操作。连接线表示Queue,各个模块通过Queue进行数据传递。

图1 GPU模拟器结构示意图

3.2.1 固定功能单元

固定功能单元包括GPU流水线中命令处理器(command processor,CP)、几何处理引擎(geometry engine,GE)、图元处理引擎(primitive engine,PE)、局部任务调度器(local task schedule,LTS)、输出合并单元(output merge unit,OMU)、输出总线(output bus,OB)。这些单元因为算法较为单一固定,可以通过对寄存器进行不同配置来实现不同的功能需求,并且其性能完全由结构设计体现。为了对这些部件进行完整的性能分析,本方法对这些单元使用周期精确的方式进行实现。

在对上述模块进行周期精确模拟时,由于有些处理单元具有多个流水级,且每个流水级又包括多级细分流水级,所以在进行模拟器实现时,本方法通过两层逆序流水的方式对图元处理引擎进行实现。下文使用图元处理引擎的实现方式进行说明。

图元处理引擎结构各流水级完成各种不同数据的乘加运算或其他数学运算,所有运算部件设计为全流水部件,流水级内部同样实现更细粒度的周期模拟。流水级内部通过虚假执行与逆序流水的方式实现细分流水。图2表示2个流水级之间的数据传递与数据计算,每一流水级包括4级细分流水级。如第1步所示,Clock函数执行时,后序流水级首先判定其最后一级细分流水级是否为空,如果为空,则将其前3级细分流水数据传递至后一级细分流水级,同时将第1级细分流水级标为空。如第2步所示,当前序流水级最后1级细分流水级不为空,且后序流水级第1级细分流水级为空时,前序流水级将数据传递至后序流水级,后序流水级直接将数据进行计算,并将结果写入后序流水级第1级细分流水级。如第3步所示,前序流水级进行流水级内细分流水级数据传递。图元处理引擎将整条流水线逆向调用所有流水级的Clock操作,来实现整条流水线的并行周期执行。

图2 Clock函数逆序流水实现方式

3.2.2 光栅化单元

光栅化单元是图元处理引擎中一个固定算法单元,本模拟器光栅化单元基于Larrabee[17,18]算法进行实现,该算法使用递归算法来实现。高级语言可以通过使用栈这一数据结构来保存递归算法的中间数据,但递归中无法预知递归调用的深度,继而无法预知中间结果数据量的大小。而且在硬件设计中,存储单元代价比较大,所以不便于使用单纯意义上的递归程序来实现光栅化算法。本工作中GPU模拟器通过将光栅化核心算法单元复制多份来实现不同层级的递归调用,光栅化单元分为7级。第1级负责根据接受到的数据生成光栅化所必需的数据结构,其余流水级将宽度为2n正方形片段数据生成宽度为2(n-1)的正方形片段数据,然后将产生的结果传递至其后一级流水级。这种结构通过增大逻辑单元面积来减小存储单元的消耗,解决了递归深度不可预知的问题,同时稳定地保证了光栅化单元每周期产生1组4×4的像素点数据的速率,使光栅化部件不会成为整条流水线的瓶颈。

3.2.3 可编程流处理器单元

可编程流处理器单元支持OpenGL 2.0标准中的统一着色器功能,统一着色器可执行顶点着色器与片段着色器2种着色器程序,模拟器实现为4份,在图1中由SP0、SP1、SP2、SP3表示。可编程流处理器与传统较为简单多流水级CPU的结构类似,包括取指、译码、执行、写回等流水级,不易使用C++串行语言进行模拟,所以可编程流处理器单元实现为功能级模拟。GPU模拟器配套开发环境下的编译器将OpenGL程序中编写的着色器程序编译为对应GPU模拟器流处理器的汇编代码,在功能级模拟下流处理器每拍直接完成一条指令。

4 实 验

为了验证本文提出模拟器的3D图形算法正确性验证的功能与性能分析的功能,本文采用glmark2[19]测试程序对GPU模拟器进行实验测试。glmark2是一款由Alexandros Frantzis与Jesse Barker开发的OpenGL API程序测试集,包括涵盖了OpenGL 2.0 API[20]大部分功能的多个测试场景,这些测试场景所实现的图片效果较为简单,可以轻易判定功能实现的正确性。实验分为3D图形正确性验证与算法性能验证两部分展开。

4.1 3D图形算法正确性验证

本文通过对glmark2中build测试项的正确性分析来表现模拟器3D图形算法正确性验证的功能。

在3D图形算法正确性验证实验中,本文将商业显卡GPU执行OpenGL程序渲染得到的图片与模拟器渲染得到的图片进行对比。为确保数据一致性,商业显卡GPU所执行的OpenGL程序输入数据也来自于本文中使用的模拟器输入数据。

GPU模拟器绘制图片与商业显卡GPU绘制的图片存在差异与错误2种不同。差异是GPU进行具体实现时选择了不同实现方式而引起的不同,例如固定功能管线使用大量的数学运算实现复杂的图形算法,不同GPU设计人员在选择不同的数据计算精度与不同的数据传输精度时,将不可避免地引入差异。这种差异在商业显卡,如AMD GPU与Nvidia GPU之间同样有体现。它们通常表现为像素点的颜色值偏差与像素点的位置偏差,但这并不影响图形应用的效果展示,且肉眼无法分别。图形功能性错误则是由于固定功能管线中图形算法的错误选取或者错误实现引起的,也有可能是因为可编程单元中指令的错误实现而引起。这种错误通常表现为模型位置大幅偏移、像素点缺失、像素颜色值错误,肉眼可轻易辨别。

对比实验中,商业显卡GPU实验环境为操作系统是Fedora 28,GPU为Nvidia 1660Ti,驱动程序为NVIDIA-Linux-x86_64-418.88。

图3是商业显卡GPU环境下build测试项的标准渲染结果,图4是GPU模拟器渲染结果。对比发现,肉眼无法看出2图之间的差别。对图3与图4进行逐像素对比,对比方式为对2图中每一相同位置像素值进行做差运算,差值结果为正数,则将差值数据保存至图5,差值结果为负数,则将差值数据绝对值保存至图6。对图5与图6进行对比,可以发现图5呈现出build测试场景的下边沿,图6则呈现出build测试场景的上边沿,表示图3与图4存在轻微的位置偏移,这是由于光栅化算法的实现不同所引起,属于差异而不是错误。而图5与图6中除了模型边沿数据,不再有其他差别,表明GPU模拟器对build测试项绘制正确。

图3 商业显卡GPU绘制效果图

图4 GPU模拟器绘制效果图

图5 差异值正值效果图

图6 差异值负值效果图

4.2 算法性能验证

本文选取Intel曾经在Larrabee论文中提到的结构光栅化算法来表现模拟器性能评估的功能。

结构光栅化算法根据待光栅化三角形的包围框数据,将屏幕空间对应的区域划分为多个正方形Tile,通过检测每个Tile的4个顶点与三角形3条边的位置关系来判定当前Tile是否与三角形产生了覆盖关系。这一方法虽然效率比较高,但并不能保证所有被判定为覆盖的Tile是真正地与三角形产生覆盖关系,如图7所示,Tile被判定为与黑色小三角形覆盖,但其实并没有覆盖。Larrabee论文表示可以通过增加包围框测试对结果进行进一步确认,这样可以减少被误判定为与三角形虚假覆盖的Tile个数,但是该论文也表明,无法确认增加包围框测试是否会提升光栅化性能。

本文通过对GPU模拟器实现2种不同算法来对增加包围框是否对光栅化算法有明显提升这一结论进行验证。光栅化操作只与图形程序中待绘制模型的几何特性有关,在删去glmark2中重复模型后,选取了build、shadow、refract、buffer、bump、loop、jellyfish、ideas、terrain测试项进行实验。

图7 递归光栅化算法[19]

如3.2节与Larrabee论文所述,本文将光栅化算法实现7级处理。第1级接受128×128的Tile数据,将该Tile等分为4个64×64的SubTile,通过接受点与拒绝点测试算法测试后输出每一个SubTile与三角形的覆盖状态,覆盖状态为True的SubTile将作为第2级的输入数据继续进行测试。图8表示算法测试结果,其中build、shadow、refract、ideas、terrain在第6级与第7级表现出超过10%的性能提升,refract在第6级表现出最高31.1%的性能提升;buffer、loop、jellyfish在第5级表现出超过10%的性能提升;bump性能提升并不明显;而除了bump外,各个模型在第1级第2级第3级几乎没有性能提升。结合各个模型不同像素数目,综合计算得出这9个测试模型的加权平均性能提升了10.11%。结果表明在增加包围框测试后,光栅化算法得到了明显的性能提升。

图8 包围框算法优化前后对比图

5 结 论

GPU模拟器通过使用高级语言模拟仿真实现硬件描述语言,在处理器结构设计前期起到重要的验证作用。本文基于GPU由固定功能管线与可编程流处理器单元构成这一特点,同时基于GPU各部件天然解耦合的性质,提出半周期精确的GPU模拟器设计方法。这一方法基于逆序流水与虚假执行的方式,将固定功能管线实现为周期精确模拟,将可编程流处理器单元实现为指令级模拟。该方法降低了GPU模拟器开发成本,同时也降低了GPU模拟器使用者对模拟器的学习成本。

本文基于此方法设计并实现了GPU模拟器。该模拟器实现了OpenGL 2.0 API,在配套使用GPU模拟器驱动程序的情况下,可执行完整的OpenGL 2.0图形程序。本文选取了glmark2测试集对GPU模拟器进行验证,同时选取了Larrabee中结构光栅化算法进行算法性能评估。模拟器使用者可以基于模拟器驱动程序运行其他OpenGL 2.0程序,还可以对该模拟器增加新的功能与新的算法,同时也可以使用其他OpenGL 2.0程序作为模拟器的输入,进行不同算法的功能正确性验证与性能评估。

猜你喜欢
模拟器光栅流水
了不起的安检模拟器
盲盒模拟器
划船模拟器
流水
文苑(2020年10期)2020-11-07 03:15:26
流水有心
天津诗人(2017年2期)2017-11-29 01:24:12
CDIO教学模式在超声光栅实验教学中的实践
基于LabView的光栅衍射虚拟实验研究
前身寄予流水,几世修到莲花?
视野(2015年6期)2015-10-13 00:43:11
动态飞行模拟器及其发展概述
落红只逐东流水
海峡姐妹(2014年5期)2014-02-27 15:09:38