在我自己构建的MFC程序中,我有一些奇怪的CPU使用问题。
我加载了一个大约360k点的点云,一切正常(我使用VBO缓冲区,这是我理解的方式吗?)。我可以随意移动它并注意没有不利影响(CPU使用率非常低,GPU完成所有工作)。但是在某些角度和缩放值下,我看到我的一个处理器上的CPU峰值!然后,我可以改变角度或缩放一点,它将再次下降到0左右。这种情况更有可能发生在大窗口而不是小窗口。
我测量程序的FPS并且它始终处于65,但是当CPU峰值达到它时,它通常会下降大约10个单位到55.我还测量SwapBuffers的时间,并且在正常操作期间它大约为0-1 ms。一旦CPU峰值达到它大约20毫秒,所以很明显在该功能中突然变得非常难以计算(对于GPU我猜?)。这个东西不在DrawScene函数中(这是一个人们期望在糟糕的实现中吃CPU的函数),所以我有点不知所措。
我知道这不是由于可见点的数量,因为这可能就像在整个云上的数据的子部分一样容易发生。我试图移动它,看看它是否与深度缓冲,剪切或类似相关,但它似乎完全随机的角度创建问题。但它看起来确实有些可重复;将模型移动到一个滞后的位置,再次移动时会变得迟钝。
我是OpenGL的新手,所以我做出一些完全明显的错误并非不可能。
这就是渲染循环的样子(它通过1 ms周期的定时器事件在MFC应用程序中运行):
// Clear color and depth buffer bits
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw OpenGL scene
OGLDrawScene();
unsigned int time1 = timeGetTime();
// Swap buffers
SwapBuffers(hdc);
// Calculate execution time for SwapBuffers
m_time = timeGetTime() - time1;
// Calculate FPS
++m_cnt;
if (timeGetTime() - m_lastTime > 1000)
{
m_fps = m_cnt;
m_cnt = 0;
m_lastTime = timeGetTime();
}
答案 0 :(得分:1)
我注意到了(至少一段时间后),ATI的驾驶员往往喜欢旋转等待太过激进,而NVidia驱动程序往往是中断驱动的。从技术上讲,旋转等待更快,假设您没有更好的事情要做。不幸的是,今天你可能在另一个主题上做了更好的事情。
我认为OP的显示驱动程序可能确实在旋转等待。
答案 1 :(得分:0)
好的,所以我想我已经弄清楚这是怎么发生的。
首先,WM_TIMER消息似乎不会比每15毫秒更频繁地生成,即使在使用timeBeginPeriod(1)时,至少在我的计算机上也是如此。这导致我看到的标准65 fps。
一旦场景渲染时间超过15毫秒,SwapBuffers就会成为限制因素。 SwapBuffers似乎忙于等待,这导致一个核心100%的CPU使用率发生这种情况。这不是在某些摄像机角度发生的事情,而是根据当时屏幕上显示的点数而流动改变fps的结果。只要渲染发生在超过15毫秒的时间并开始等待SwapBuffers,它就会出现尖峰。
在类似的说明中,有没有人知道像“glReadyToSwap”这样的功能?一个函数,指示缓冲区是否可以交换?这样我可以选择另一种方法以更高的分辨率(例如1毫秒)进行渲染,然后每个ms检查缓冲区是否准备好交换,如果它们不只是等待另一个ms,以便不忙等待。