怎样才能带好一条流水线

更新时间:01-24 教程 由 花心症 分享

怎样才能带好一条流水线?

先说说硬件的流水线首先要明确一个概念,GPU的流水线不是串行的,打个比方,下面一段OpenGL代码,

CPU执行1的时候,并不会要求1所表示的指令塞入到GPU,让GPU执行完后CPU才开始执行2。硬件的设计上,CPU和GPU是通过一个所谓的push buffer连接的,push buffer可以看成一个fifo的queue,CPU把指令塞入push buffer,GPU从push buffer中读取。回到上面那段代码,CPU执行代码1的时候,就是把它塞入到push buffer就返回了,它并不管GPU是不是执行完成,接着执行代码2,以此类推。然后在GPU内部也有好几个模块,简化下大致有FE,frontend是GPU的前段,负责从push buffer中读数据,之后是PD,就是assember,随后是vertex shader之类之类的。GPU硬件是时钟驱动的(clock domain)。举例说,第一时钟周期,当FE读取一个命令,并把命令传达给流水线上的下一个模块PD,在第二个时钟周期,PD才能把这个命令消化执行。以此类推,所以每个时刻基本上硬件流水线上的每个模块都是在工作着,虽然工作在不同的数据上。这就回答了题主的问题一,流水线不会空。如果要实现一个软件流水线,严格意义上讲也要基于时钟周期,每一个模块之间要用FIFO相连,每一个模块可以是一个独立的线程。这样可以保证最大的并行。最后说一下,图元不是1个1个往下走的,一个个往下走会有一个很大的问题,就是所有的cache命中率,这个是另外一个大题目,以后再说。图元是一批批往下送的。拿下面一块代码来说GPU的FE是一次把1200个三角形往流水线上塞得,PD会做一些优化,把1200个三角形分成几个批次,提到cache命中率,之后流水线上的大多数模块都是在一个时钟周期内处理多个三角形,而不是一个。华丽丽的分割线=============================FAQ:1、意思就是说硬件图形管线是完全基于硬件并行于主程序的?实现软件渲染器也应该模拟这种并行性才能发挥流水线最大效率?我之前看了一些软件渲染器的实现,似乎都没有这一茬,好像流水线都是CPU串行的,所以会产生这样的疑问。取决于你的软件模拟器是想实现功能,还是想模拟硬件,如果是一个模拟器着重于功能,可以抛弃这种clock domain的硬件设计和push buffer等fifo;如果一个模拟器需要通过软件模拟硬件,就需要这么去做,这也是GPU硬件公司里面设计硬件的内容,就先拿软件,一般是C++,写一个模拟器,模拟出新功能,然后衡量性能的提升。2、按照你的说法,如果流水线渲染完一批数据要16ms,要保证流水线永远不空,主程序的写入数据周期是不是要小于16ms?这样的话,如果流水线的执行速度远大于主程序写入速度,岂不是依然要拖慢渲染效率?而且主程序和渲染结果将会不同步?所以说图形程序有CPU bound和GPU bound的说法。如果CPU的写入速度慢,GPU在空等,那么就是CPU bound,反之就是GPU bound。程序优化的目标就是大家都满载,不要空等。这个应用程序优化的范畴。3. GLBufferData怎么执行的呢,是内部拷贝一份,放入队列;还是等队列那边从内存取完数据再返回glBufferData是一个blocking call,CPU会等待GPU完全把数据从CPU搬到GPU后才返回执行下一条命令。具体的工作机制,请参看俺的SIGGRAPH Asia 2015 course,Modern OpenGL Programming。http://lihw.github.io/pub/opengl.pdf

声明:关于《怎样才能带好一条流水线》以上内容仅供参考,若您的权利被侵害,请联系13825271@qq.com
本文网址:http://www.25820.com/tutorial/14_2198144.html