许多图形编程资源似乎建议使用三重缓冲数据,以避免在GPU上进行同步。这里有一些例子:
OpenGL见解-异步缓冲区传输
苹果的最佳做法(三重缓冲)
而另一个来源说:
GPU和CPU异步运行...但是还有另一个因素:驱动程序。该驱动程序也可能异步运行(在桌面驱动程序实现中,它经常发生)。为了解决这个甚至更复杂的同步方案,您可以考虑使用三重缓冲:
一个cpu缓冲区
一个给司机
一个为GPU
这样,管道中就不会出现停顿,但是您需要为数据牺牲更多的内存。
-
驱动程序实际上是第三个缓冲区吗?第三个缓冲区试图解决驱动程序上的哪个同步问题?感觉我们可以避免只使用两个缓冲区进行所有同步。
三重或双缓冲问题是在持久映射缓冲区的上下文中。我还没有使用持久映射的缓冲区,但是我已经阅读了Nvidia的演示(现代OpenGL如何从根本上减少驱动程序开销),并讨论了该主题并解释了其工作原理。只有在避免在每帧传输新数据时出现停顿时才需要三重缓冲:
您有责任不踩踏飞行中的数据。
为什么是3倍?
1x:GPU现在正在使用什么。
2倍:驱动程序持有什么,准备好使用GPU。
3x:您正在写的内容。
3倍应该〜保证有足够的缓冲空间*…
在开始写入新数据之前,请使用围墙以确保渲染完成。
上述演示中引用的高效缓冲区管理[McDonald 2012]还提供了有关适当缓冲区管理的更深入的信息。
另请参见OpenGL Wiki,其中概述了有效的缓冲区更新算法。
只要保护缓冲存储器区域不被篱笆覆盖,您甚至可以使用单个缓冲的顶点缓冲区。但是,这将使性能大大降低,因为您将失去异步内存传输的好处。写操作将等待之前的渲染操作完成,从而序列化更新和绘制阶段。
同样,所有这种双重和三次缓冲仅与更改每个帧的流顶点数据有关。