使用vsync(OpenGL)时100%的CPU利用率

时间:2014-02-21 04:30:11

标签: c++ opengl driver nvidia vsync

这是一个非常简单的测试程序。禁用vsync时,该程序以100FPS运行,几乎占用CPU的0%。当我启用vsync时,我获得60FPS和25%(4核系统上一个核心的100%)CPU利用率。这是使用Nvidia GPU。在线搜索引导我建议禁用Nvidia控制面板内的“多线程优化”。这确实会降低CPU利用率,但只会降低10%。此外,如果我在SwapBuffers之后删除了睡眠调用,即使禁用了多线程优化,我也会再次获得25%的利用率。任何人都可以对此有所了解吗?难道我做错了什么? Nvidia的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);
}

1 个答案:

答案 0 :(得分:7)

我毫不犹豫地将此作为答案,因为我真的不知道“答案”,但希望我能对此有所启发。

我也有一个nVidia GPU,我也注意到了同样的事情。我的猜测是驱动程序本质上是等待旋转:

while(NotTimeToSwapYet()){}

(或任何花哨的驱动程序版本)。

使用process hackernvoglv32.dll的线程中抽取一些堆栈跟踪,大约99%的时间位于列表顶部的东西是

KeAcquireSpinLockAtDpcLevel()

通常位于

之类的下游

KiCheckForKernelApcDelivery()EngUnlockDirectDrawSurface()

我对Windows驱动程序编程的熟悉程度不足以称之为结论,但它肯定不会告诉我我也错了。

看起来你也没有做任何明显错误的事情。根据我的经验,非独占Windows应用程序中的交换时间非常痛苦:涉及大量的试验和错误,以及不同系统之间的大量可变性。据我所知,没有“正确”的方法可以一直很好地工作(请有人告诉我,我错了!)。

在过去,我已经能够依赖vsync来保持较低的CPU使用率(即使它确实使响应性降低了一些),但似乎不再是这种情况。我最近从DirectX切换到OpenGL,所以我无法告诉你这是否是nVidia驱动程序最近的更改,或者它们是否仅仅针对vsync处理DX和OpenGL。