【发布时间】:2011-08-01 00:42:11
【问题描述】:
在我自己构建的 MFC 程序中,我遇到了一些奇怪的 CPU 使用问题。
我加载了大约 360k 点的点云,一切正常(我使用 VBO 缓冲区,这是我理解的方法吗?)。我可以随意移动它,并且没有注意到任何不利影响(CPU 使用率非常低,GPU 完成了所有工作)。但是在某些角度和缩放值上,我看到我的一个处理器上的 CPU 峰值!然后我可以稍微改变角度或缩放,它会再次下降到 0 左右。大窗口比小窗口更有可能发生这种情况。
我测量了程序的 FPS,它一直保持在 65,但是当 CPU 达到峰值时,它通常会下降大约 10 个单位到 55。我还测量了 SwapBuffers 所花费的时间,在正常运行期间它大约是 0-1 毫秒。一旦 CPU 达到峰值,它就会上升到大约 20 毫秒,所以很明显,在那个函数中计算突然变得非常困难(我猜是 GPU 吗?)。这东西不在 DrawScene 函数中(这是一个在糟糕的实现中会消耗 CPU 的函数),所以我有点茫然。
我知道这不是由于可见点的数量,因为这很容易发生在数据的一个子部分上,就像在整个云上一样。我试图移动它,看看它是否与深度缓冲区、剪辑或类似的有关,但似乎完全随机的是什么角度会产生问题。不过,它似乎确实有些可重复;将模型移动到曾经滞后的位置,再次移动时会滞后。
我是 OpenGL 的新手,所以我犯了一些完全明显的错误并非不可能。
这是渲染循环的样子(它在 MFC 应用程序中通过 1 毫秒周期的计时器事件运行):
// 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();
}
【问题讨论】:
-
我在您的问题中看不到太多实际代码。你能多提供一点吗?只是为了澄清一下:您是否每秒调用一千次 DrawScene 和 SwapBuffers?这是一个巨大的数字。
-
如果您参考 1000 值,它只是确定何时经过 1 秒(1000 毫秒)并更新 fps 值。它每秒循环大约 65 次,但我无法修改,因为它取决于 opengl。至于代码,我真的不知道该显示什么,代码很多......
-
我指的是您的陈述“它是通过具有 1 ms 周期的计时器事件在 MFC 应用程序中运行的”。因此我想问一下这是否真的经常被调用以及你的计时器的分辨率是多少。
-
好吧,我现在明白你的意思了。我确实在一个周期为 1 毫秒的计时器上运行它,但即便如此循环每秒只运行 65 次......这有点奇怪,特别是考虑到整个循环的执行时间是正常情况下大约 0-1 毫秒:-/
-
我们的想法是尽可能地精简代码以识别问题。如果您移除部件并且问题不再存在,这(在大多数情况下)是问题所在的明确提示。另一方面,如果您只剩下几行代码并且问题仍然存在,那么分析就会简单得多(对我们而言,对您而言也是如此)。