OpenGL,测量 GPU 上的渲染时间

Posted

技术标签:

【中文标题】OpenGL,测量 GPU 上的渲染时间【英文标题】:OpenGL, measuring rendering time on gpu 【发布时间】:2015-07-18 06:10:16 【问题描述】:

我有一些很大的性能问题here

所以我想在 gpu 端进行一些测量。

通过阅读thread,我围绕我的绘图函数编写了这段代码,包括 gl 错误检查和 swapBuffers()(确实禁用了自动交换)

        gl4.glBeginQuery(GL4.GL_TIME_ELAPSED, queryId[0]);
            
            draw(gl4);

            checkGlError(gl4);

            glad.swapBuffers();
        
        gl4.glEndQuery(GL4.GL_TIME_ELAPSED);
        gl4.glGetQueryObjectiv(queryId[0], GL4.GL_QUERY_RESULT, frameGpuTime, 0);

并且由于 OpenGL 渲染命令应该是 asynchronous(驱动程序可以在将它们全部一起发送之前缓冲多达 X 个命令),我的问题基本上是:

上面的代码是正确的

我是正确的假设在新帧开始时,所有先前的 GL 命令(来自前一帧)都已在 gpu 上发送、执行和终止

我假设当我使用glGetQueryObjectivGL_QUERY_RESULT 获得查询结果时,到目前为止所有的GL 命令都已终止,这是对的吗?那就是OpenGL会等到结果可用(从线程)?

【问题讨论】:

【参考方案1】:

是的,当您查询计时器时,它将阻塞直到数据可用,即直到 GPU 完成查询开始和结束之间发生的所有事情。为避免与 GPU 同步,您可以使用GL_QUERY_RESULT_AVAILABLE 检查结果是否已经可用,然后再读取它们。这可能需要不那么直接的代码来密切关注打开的查询并定期检查它们,但它对性能的影响最小。每次都等待价值肯定会扼杀你的表现。

编辑:为了解决您的第二个问题,交换缓冲区并不一定意味着它将阻塞,直到操作成功。您可能会看到这种行为,但很可能它只是一个隐含的glFlush,并且命令缓冲区还不是空的。这也是更需要的行为,因为理想情况下,您希望立即开始下一帧并保持 CPU 命令缓冲区充满。不过,请查看实现文档以获取更多信息,因为这是实现定义的。

编辑 2:顺便说一句,检查错误最终可能会成为隐式同步,因此当您等待命令流中的错误检查时,您可能会看到命令缓冲区清空。

【讨论】:

我知道这是性能杀手,但目前我只关心纯渲染功能需要多少时间 很公平。我只是把它放在那里作为参考,所以你知道你会进入什么

以上是关于OpenGL,测量 GPU 上的渲染时间的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 OpenGL 监控 Java 中的 GPU 使用情况?

GPU渲染流程

OpenGL 3.3 两个 GPU 上的两个不同结果 nVidia Optimus 与阴影映射

使用 OpenGL 渲染时 CPU 和 GPU 之间的数据丢失

优化流媒体vbo openg

opengl vbo建议[关闭]