SwapBuffer中的重复停顿

我目前正在使用不同的“设置”在OpenGL 4.5中实现的testing场景上进行测量。

我注意到,如果我有一个非常高的FPS数量(在这个具体情况下是1550),SwapBuffer确实会停止大约每20帧,帧时间从〜0.5ms增加到〜1.2ms。 这只有在FPS高于某个阈值时才会发生。 我已经知道它与预渲染帧(我禁用NV控制面板中的预渲染帧)无关,它也与wglSwapIntervalEXT(0)使用wglSwapIntervalEXT(0)

有人能告诉我什么可能造成这个摊位/滞后或wathever。

我附上了用Nsight制作的两张截图。

第一个显示“健康”的设置没有摊位: 在这里输入图像描述

而秒数显示与摊位的设置:

在这里输入图像描述

不幸的是,这些不明原因的摊位可能很常见,很难完全回答。

为了准确回答这个问题,我们必须知道在这个短暂的失速期间司机内部发生了什么。 NVidia和AMD仅向我们提供有关其驱动程序行为的大量信息。 有时我们不得不猜测。

有时驾驶员的行为并不完全合乎逻辑。 驱动程序针对当前游戏所需的各种用例进行了优化。 这意味着其他用例的效率会降低。 以1550fps运行并不是一种正常的情况,所以我们不能期望驱动程序针对这种情况进行优化。

有一点需要考虑的是GPU事件是使用FIFO队列从CPU去同步的。 队列包含渲染命令(比如bind-render-target,copy-memory-to-constant-buffer,draw-indexed等)。 CPU将命令写入队列。 在某些不同步的时间,GPU将从队列中读取这些命令。 我们可以把它看作生产者/消费者模式。

在某些情况下,CPU可能比GPU运行得更快。 这意味着队列会变得越来越长。 对于非常简单的帧,队列可能会变成几帧。

有几个API命令来控制驱动程序如何管理这个队列。 因此,驱动程序可以自由限制队列的大小(即使这意味着同步CPU和GPU)。

我认为这可能是最可能的解释…驱动程序可能已经决定,CPU已经远远超前于GPU。 所以它会注入一些小暂停来放慢CPU速度,并让GPU赶上。

还有其他的可能性…也许驱动程序正在GPU内存上做一些碎片整理工作? 甚至可能是因为nsight导致了停顿(也许做一些管理它的分析缓冲区的工作)。

如果你想探索更多,有一些工具,你可以尝试:

GPUViewhttp://graphics.stanford.edu/~mdfisher/GPUView.html这个configuration文件的Windows驱动程序模型内的事件。 你甚至可以看到一些排队行为,其中命令包停滞等待GPU时间。

启用configuration文件的驱动程序 – 如果您有权访问nvidia或AMD的开发人员支持,则可以使用可以configuration其驱动程序代码的工具。 这可以表明驾驶员在做什么。

不过,我真正的建议是尝试剖析一个真实的案例。 驱动程序代码和你的引擎代码在1550帧的行为并不是那么重要。 如果你可以在实际情况下重现相同的拖延行为(例如渲染一个游戏场景),那么这可能是一个更有效率的探索。