1. 程式人生 > c++ > 使用vsync(OpenGL)時100%的CPU利用率

【c++】使用vsync(OpenGL)時100%的CPU利用率

這是一個非常簡單的測試程式。禁用vsync時,該程式以100FPS的速度執行,實際上消耗了0%的CPU。啟用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);
}

解決辦法

我不願給出答案,因為我並不真正知道“答案”,但希望我能對此有所啟發。

我也有一個nVidia GPU,我注意到了同樣的事情。我的猜測是驅動程式本質上是在等待旋轉:

while(NotTimeToSwapYet()){}

(或該驅動程式的任何高階版本)。

使用process hackernvoglv32.dll的執行緒中取樣一些堆疊跟蹤,大約99%的時間位於列表頂部的是
KeAcquireSpinLockAtDpcLevel()
通常在諸如
KiCheckForKernelApcDelivery()EngUnlockDirectDrawSurface()
我不太熟悉Windows驅動程式程式設計,不能稱之為結論性的,但是它當然也不能告訴我我也不對。

而且您似乎也沒有做任何明顯錯誤的事情。根據我的經驗,非排他性Windows應用程式中的交換時間真的很痛苦:涉及很多試驗和錯誤,並且不同系統之間存在很多可變性。據我所知,沒有一種“正確”的方法可以一直有效(請有人告訴我我錯了!)。

過去,我一直可以依靠vsync來保持較低的CPU使用率(即使確實使響應速度降低了一點),但現在似乎不再如此了。我是最近才從DirectX切換到OpenGL的,所以我無法告訴您這是否是nVidia驅動程式中的最新更改,或者它們是否在對待vsync方面只是區別對待DX和OpenGL。