2021年3月2日

什么是Draw Call?为什么Draw Call 多了会影响帧率?

Draw Call 本身的含义很简单,就是CPU调用图像编程接口,如OpenGL 中的glDrawElements 命令或者DirectX 中的DrawlndexedPrimitive命令,以命令GPU 进行渲染的操作。

一个常见的误区是, Draw Call 中造成性能问题的元凶是GPU,认为GPU 上的状态切换是耗时的,其实不是的,真正“拖后腿”其实的是CPU。

为什么Draw Call 多了会影响帧率?

我们先来做一个实验:请创建10 000 个小文件,每个文件的大小为1KB,然后把它们从一个文件夹复制到另一个文件夹。你会发现,尽管这些文件的空间总和不超过10MB ,但要花费很长时间。现在,我们再来创建一个单独的文件,它的大小是10MB,然后也把它从一个文件夹复制到另一个文件夹。而这次复制的时间却少很多!这是为什么呢?明明它们所包含的内容大小是一样的。原因在于,每一个复制动作需要很多额外的操作,例如分配内存、创建各种元数据等。如你所见,这些操作将造成很多额外的性能开销,如果我们复制了很多小文件,那么这个开销将会很大。

渲染的过程虽然和上面的实验有很大不同,但从感性角度上是很类似的。在每次调用Draw Call 之前, CPU 需要向GPU 发送很多内容,包括数据、状态和命令等。在这一阶段, CPU 需要完成很多工作,例如检查渲染状态等。而一旦CPU 完成了这些准备工作, GPU 就可以开始本次的渲染。GPU 的渲染能力是很强的,渲染200 个还是2 000 个三角网格通常没有什么区别,因此渲染速度往往快于CPU 提交命令的速度。如果Draw Call 的数量太多, CPU 就会把大量时间花费在提交Draw Call 上,造成CPU 的过载​