使用vsync(OpenGL)时CPU利用率为100%
100% CPU utilization when using vsync (OpenGL)
这里有一个非常简单的测试程序。当vsync被禁用时,这个程序以100FPS的速度运行,几乎占用了0%的CPU。当我启用vsync时,我可以获得60FPS和25%(在4核系统中为一核的100%)的CPU利用率。这是使用Nvidia GPU。通过在线搜索,我得到了在英伟达控制面板内禁用"多线程优化"的建议。这确实降低了CPU利用率,但仅降低到10%。此外,如果我在SwapBuffers之后删除对睡眠的调用,即使禁用了多线程优化,我也能再次获得25%的利用率。有人能解释一下吗?我做错什么了吗?英伟达的OpenGL实现是否存在无可救药的缺陷?
#include <GLFW/glfw3.h>
#include <thread>
#include <cstdlib>
#include <cstdio>
int main(int argc, char *argv[])
{
if(!glfwInit())
exit(EXIT_FAILURE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Vsync Test", nullptr, nullptr);
if(!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
#ifdef USE_VSYNC
glfwSwapInterval(1);
#else
glfwSwapInterval(0);
#endif
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
double lastTime = glfwGetTime();
double nbFrames = 0;
while(!glfwWindowShouldClose(window))
{
double currentTime = glfwGetTime();
nbFrames++;
if (currentTime - lastTime >= 1.0)
{
char cbuffer[50];
snprintf(cbuffer, sizeof(cbuffer), "OpenGL Vsync Test [%.1f fps, %.3f ms]", nbFrames, 1000.0 / nbFrames);
glfwSetWindowTitle(window, cbuffer);
nbFrames = 0;
lastTime++;
}
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
glfwPollEvents();
//limit to 100FPS for when vsync is disabled
std::chrono::milliseconds dura(10);
std::this_thread::sleep_for(dura);
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}
我不太愿意给出这个答案,因为我真的不知道"答案",但希望我能为它提供一些线索。
我也有一个nVidia GPU,我也注意到了同样的事情。我的猜测是,驱动程序本质上是旋转等待:
while(NotTimeToSwapYet()){}
(或者不管它的高级驱动程序版本是什么样子)。
使用进程黑客从nvoglv32.dll
的线程中采样一些堆栈跟踪,大约99%的时间处于列表顶部的是
KeAcquireSpinLockAtDpcLevel()
它通常在之类的东西的下游
KiCheckForKernelApcDelivery()
和EngUnlockDirectDrawSurface()
我对Windows驱动程序编程还不够精通,不能称之为结论性的,但它也不能告诉我我错了。
看起来你也没有做错什么。根据我的经验,在非独占的Windows应用程序中交换时间真的很痛苦:涉及到很多尝试和错误,不同系统之间也有很多可变性。据我所知,没有一种"正确"的方法可以一直有效(请有人告诉我我错了!)。
在过去,我一直能够依靠vsync来保持低CPU使用率(即使它确实降低了响应速度),但现在似乎不再是这样了。我最近才从DirectX切换到OpenGL,所以我无法告诉你这是nVidia驱动程序最近的变化,还是他们只是在vsync方面区别对待DX和OpenGL。
交换缓冲区后,调用DwmFlush();
,它将不再使用100%的cpu!
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 在模拟器中使用并集来模拟CPU寄存器有多合适
- 编写一个函数以使用 n 百分比的 CPU 使用率
- 如何禁用 CPU 的无序执行
- CPU 瓶颈;处理具有许多非静态对象的 3D 场景渲染的简单方法
- 分别测量每个线程上花费的 CPU 时间(C++)
- 什么时候最好在子进程中使用 CPU 或 I/O 密集型代码 [ C++ ]
- 在程序运行时监视 VxWorks 中的任务 CPU 利用率
- 对于等待以 std::future wait() 返回的函数的 CPU 使用率或检查标志在循环中休眠一段时间哪个更好?
- 您选择的 CPU 不支持 x86-64 指令集
- 使用vsync(OpenGL)时CPU利用率为100%
- 使用LIBPROC在C 中找到CPU利用率
- 在 XCODE 5 中将 CPU 利用率提高到 100% 以上
- 100% CPU 利用率在 gettimeofday、QTime 或 QLabel->setText
- 使用MQTT deamon时CPU利用率高.
- 如何在linux中以1秒粒度找到精确的cpu利用率
- 如何为适当的CPU利用率编写代码
- 如何以编程方式从工作线程获得父线程和兄弟线程的CPU利用率
- XP 应用程序不会增加 CPU 利用率
- 在C++中查找系统的CPU利用率