glFinish()与glFenceSync()+glClientWaitSync()的区别

4

运行和执行有什么区别吗?

glFinish()

并运行

glFenceSync(...)
glClientWaitSync(...)

使用大的超时时间?

我的目标是:我运行一系列OpenGL命令,我想计算每个命令需要的时间。如果不使用上述命令,所有的命令都将被进行管线/缓存处理,看起来好像最后一个命令占用所有的处理时间。

timer start

Run Opengl part 1

sync / glFinish
timer measure

Run Opengl part 2

sync / glFinish
timer measure

...

所以我正在努力找出如何最好地测量各个部分的“速度”,而不会对整体运行时间产生太大影响。

1个回答

7

您提到的所有选项都会影响应用程序的性能,因为它们会阻塞管道。OpenGL中测量时间的现代方式是使用计时器查询:您告诉OpenGL在GPU上执行查询时应保存时间戳,因此不需要在GPU和CPU之间进行同步。代码可能如下所示:

GLuint64 startTime, stopTime;
unsigned int queryID[2];

// generate two queries
glGenQueries(2, queryID);
...
// issue the first query
// Records the time only after all previous 
// commands have been completed
glQueryCounter(queryID[0], GL_TIMESTAMP);

// call a sequence of OpenGL commands
...
// issue the second query
// records the time when the sequence of OpenGL 
// commands has been fully executed
glQueryCounter(queryID[1], GL_TIMESTAMP);
...

// get query results
// (automatically blocks until results are available)
glGetQueryObjectui64v(queryID[0], GL_QUERY_RESULT, &startTime);
glGetQueryObjectui64v(queryID[1], GL_QUERY_RESULT, &stopTime);

printf("Time spent on the GPU: %f ms\n", (stopTime - startTime) / 1000000.0);

(代码摘自Lighthouse3d.com)。

另一种选择是使用glBeginQueryGL_TIME_ELAPSED参数,该参数也在链接的文章中描述。


你可能至少想在循环中加入一个“sleep”,以便它不会占用你所有的CPU资源。 - Colonel Thirty Two
1
等待结果可用的自旋循环是不必要的。如果结果尚未准备好,获取GL_QUERY_RESULT将会阻塞。 - Reto Koradi
通常情况下,这是不可取的。我认为我没有看到任何使用计时器查询的生产代码这样做。每当您需要性能计时信息时,您都希望在不改变由于停顿直到结果可用而引起的管道行为的情况下获得它。这就像加速0-60并反复刹车回到0,并期望代表正常驾驶条件。滚动启动更具代表性的典型性能有非常不同的结果。 - Andon M. Coleman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接