简体   繁体   English

OpenGL和CPU / GPU计时器同步

[英]OpenGL and CPU/GPU timer synchronization

I'm trying to make a CPU and GPU profiler to use in a video game. 我正在尝试制作在视频游戏中使用的CPU和GPU分析器。 The goal is to have on-screen 2 graphs that give the time taken by the different tasks of a frame. 目的是在屏幕上显示2张图表,这些图表给出了帧的不同任务所花费的时间。 This is a very crude illustration of what it looks like: 这是一个非常粗糙的图示:

在此处输入图片说明

I'm using QueryPerformanceCounter (on Windows) to get the CPU time and glQueryCounter(GL_TIMESTAMP) to get GPU times. 我正在使用QueryPerformanceCounter(在Windows上)获取CPU时间,并使用glQueryCounter(GL_TIMESTAMP)获取GPU时间。

The problem is that the times I get for CPU and GPU are not relative to the same origin. 问题是我获得CPU和GPU的时间不是相对于同一起点的。 My first attempt to fix this was to make a blocking call to a GPU timestamp (with glGetInteger64v(GL_TIMESTAMP)) during the initizalization of the app, closely followed by a get of the CPU time. 解决此问题的第一个尝试是在应用程序初始化期间对GPU时间戳(使用glGetInteger64v(GL_TIMESTAMP))进行阻塞调用,紧接着获取CPU时间。 The difference between the two times allowed me to basically convert GPU times to CPU times and have both graphs synchronized. 两次之间的时间差使我基本上可以将GPU时间转换为CPU时间,并使两个图形都同步。 But after a few seconds (or minutes) the times are drifting and my graphs are not correctly synchronized anymore. 但是几秒钟(或几分钟)后,时间开始漂移,我的图形不再正确同步。

I can't make another blocking call to get a GPU time after the game has started because I don't want to loose a frame and make the game stutter. 在游戏开始后,我无法再进行一次阻塞调用来获得GPU时间,因为我不想松开框架并使游戏结结巴巴。

Did anyone try to do something like this or have any advice on how to synchronize the CPU and GPU times without hurting the performance ? 是否有人尝试做这样的事情,或者在不影响性能的情况下对如何同步CPU和GPU时间有任何建议?

I have another idea but I don't know if it's going to work well: have a separate thread make the blocking call to get the GPU time, also get the CPU time and send back the difference to the main thread somehow. 我有另一个想法,但我不知道它是否能很好地工作:有一个单独的线程进行阻塞调用以获取GPU时间,还获取CPU时间并将差异以某种方式发送回主线程。 Then the thread would sleep for a few seconds and start again. 然后线程将休眠几秒钟,然后重新开始。 I'll try this and update the post if this seem to work well. 如果效果良好,我将尝试并更新帖子。

Edit: I tried the idea above on both an AMD and an NV card and it seems to work fine. 编辑:我在AMD和NV卡上都尝试了上面的想法,它似乎工作正常。 Even when calling glGetInteger64v(GL_TIMESTAMP) lots of times (with a sleep of only 1ms between each call), it seems to have no impact on the performance. 即使多次调用glGetInteger64v(GL_TIMESTAMP)(每次调用之间只有1ms的睡眠时间),它似乎也不会影响性能。 I still need to make more in depth tests but so far, this looks like a good solution. 我仍然需要进行更多的深度测试,但到目前为止,这似乎是一个不错的解决方案。

I made a separate thread that make a blocking call to glGetInteger64v(GL_TIMESTAMP). 我创建了一个单独的线程来阻塞调用glGetInteger64v(GL_TIMESTAMP)。 It made no visible difference in performance even when waiting something stupidly small like 1ms between each call. 即使每次调用之间等待的时间都非常小,例如1ms,也没有明显的性能差异。 Although it should be noted that I already had several OpenGL contexts before this modification. 尽管应该注意的是,在进行此修改之前,我已经具有多个OpenGL上下文。

In the final code, I wait 30 seconds between each call to glGetInteger64v(GL_TIMESTAMP). 在最终代码中,我在每次调用glGetInteger64v(GL_TIMESTAMP)之间等待30秒。 It seems to be often enough to avoid any visible drifting on all the PCs I tested. 似乎足以避免在我测试的所有PC上出现任何可见的漂移。

I tested on Nvidia cards (GTX 460, GTX 660, GTX 780ti, GTX 780M) and AMD (Radeon HD 7950), all with Intel CPUs. 我在Nvidia卡(GTX 460,GTX 660,GTX 780ti,GTX 780M)和AMD(Radeon HD 7950)上进行了测试,所有显卡均使用Intel CPU。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM