以nVidiaMaxWell为例分析GPU硬件架构
SP是最小的GPU计算单元,相当于微型CPU,也称为CudaCore。
PolyMorphEngine是用来执行固定渲染步骤的硬件,一般包括这个组件
线程warp(warp)是GPU任务调度的基本单位一个warp包含32个Thread,即也就是说,GPU调度是基于32个线程的,即使只处理3个顶点,也会调度32个线程,占用32个SP进行计算,其中29个会被隐藏为Status
(1)当图形API(OpenGL/DirectX/Metal)发出DrawCall时,命令被推送到驱动程序以验证命令的有效性。指令被推送到GPU可以读取的推送缓冲区中。
(2)一段时间后或者显式调用flush命令时,驱动程序将pushbuffer中的命令发送给GPU,GPU中的主机接口(HostInterface)接收到该命令并通过前端处理它。
(3)图元分配器(PrimitiveDistributor)处理indexbuffer中的顶点数据,生成三角形簇并发送给多个GPC处理
(4)命令到达后GPC,每个SM中PolyMorphEngine中的VertexFetch模块负责通过三角形索引检索三角形数据。
(5)获取数据后,SM中的WarpScheduler开始以32个线程为一组的warp来调度处理顶点数据。Warp是一种单指令多线程(SIMT,SingleInstructionMultipleThread)实现,它同时执行相同的指令,但每个线程的数据是随时间变化的。
(6)一个warp中的线程会以lockstep的方式执行指令,没有分配数据的线程会被屏蔽,不能独立调度,必须在warp单元中,但它们是不同独立的。
(7)指令执行时间不同,特别是内存加载需要时间WarpScheduler可以继续切换到其他warp执行而不需要等待内存,因此GPU可以克服内存读取延迟。Warp在寄存器文件RegisterFile中有自己的寄存器。
(8)当warp完成顶点着色器命令的执行后,操作结果会被发送到PolyMorphEngine中的ViewportTransform模块进行处理,通常顶点着色器输出的是切割空间的坐标。,ViewportTransform对Crop顶点进行操作,进行视口变换,即屏幕映射,将顶点坐标变换为屏幕坐标。
(9)得到屏幕坐标后,就可以进行光栅化了。三角形被划分并分配给多个GPC(通常是按照屏幕图块来分配的。对于GPCRasterEngine来说,每个RasterEngine覆盖了几个屏幕图块。
(10)GPC上的RasterEngine对三角形数据进行栅格化,得到每个三角形覆盖的像素信息。这里通常进行背表面解构和z初始解构操作
(11)对于三个顶点。三角形的每个顶点都会执行一次顶点标记和ViewportTransform处理后的信息发送到RasterEngine进行光栅化以获得一些片段(位置,颜色,法线等)获得SM上的AttributeSetup会根据顶点数据进行插值以获得片段数据L1&L2缓存用于存储数据,这是为了确保片段着色器可以处理它。
(12)将分配8个2x2片段块(总共32个)。扭曲由SM中的WarpScheduler来执行着色器命令。
(13)片元着色器执行指令完成片元颜色和深度的计算目前需要基于三角形的原始API提交序列来将数据传输到ROP渲染输出单元。(RenderOutputUnit),ROP内部有很多ROP单元,ROP单元处理逐个片段的操作,例如深度测试、与FrameBuffer中的片段混合等。
(14)ROP获取片段数据,访问FrameBuffer进行逐片段操作后,将结果通过Crossbar写入FrameBuffer,渲染过程结束。
GPU中的内存分为几种类型,不同类型内存的读取速度差异较大
Shader中直接使用的寄存器内存速度很快,纹理恒定内存和全局内存相当慢。
以上流程是MaxWell桌面GPU架构的详细渲染。然而,移动GPU的架构与桌面GPU不同。
移动渲染过程基于Tile-Based架构,也称为TBR(Tile-BasedRender),对于帧中的所有DrawCall,首先执行VS顶点对象,然后相应地划分为块。到屏幕上。(Tile),基于Tile实现片段着色器(FS)。
看一个例子。如果在给定帧中提交两个DrawCall,则每个DrawCall都包含一个三角形,并且这两个三角形覆盖整个屏幕。