为什么空循环使用那么多GPU(OpenGL)?

时间:2019-01-12 22:13:56

标签: c++ opengl mingw-w64

我正在尝试使用现代OpenGL创建GUI库。但是我注意到,当其他游戏和程序正在使用我的GPU时间的约16-20%(当游戏未启动时,在主菜单上)时,我简单的glClear()和交换缓冲区调用就使用了约25-26%(在全屏模式下。

我正在使用glfw并通过以下代码进行转换:

#include <GL/glew.h>
#include <GLFW/glfw3.h>

int main() {
    if(!glfwInit()) return -1;

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_DECORATED, false);
    glfwWindowHint(GLFW_RESIZABLE, false);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    //glfwWindowHint(GLFW_REFRESH_RATE, 60);

    GLFWwindow *window = glfwCreateWindow(960, 540, "Untitled Window", nullptr, nullptr);
    if(window == nullptr) return -2;

    glfwMakeContextCurrent(window);
    if(glewInit() != GLEW_OK) return -3;
    //glfwSwapInterval(1);

    glClearColor(1, 1, 1, 1);
    while(!glfwWindowShouldClose(window)) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glfwPollEvents();
        glfwSwapBuffers(window);
    }

    glfwTerminate();
    return 0;
}

例如,Hearts of Iron IV启动器消耗了我大约GPU时间的6-7%,而我使用上述代码运行的程序大约消耗了我GPU时间的13%。

实际上,我的程序以4%开始,几秒钟后上升到13%。

我有NVIDIA的GeForce GTX 980M和Intel HD Graphics 4600(与NVIDIA不同,在上面的代码中使用〜4%)。

我的计算机出问题了吗?还是有关编译器/ api的问题?

顺便说一句,我已经测试了带注释的部分和不带注释的部分,并且结果非常相似。我也尝试过使用OpenGL 4,但完全没有影响。

NVIDIA和Intel GPU均启用了VSync。

1 个答案:

答案 0 :(得分:4)

在这个(看似)简单的程序中,您会看到大量使用GPU的原因,但是最大的原因是...

这不是一个空循环

例如,考虑在循环结束时进行的一行函数调用:glfwSwapBuffers(window);。这是负责指示GPU放弃当前渲染的帧并渲染下一帧的函数调用。即使没有实际绘制的对象,这仍然需要GPU重画几百万个像素(取决于您的显示器大小),并且由于您的循环只会等待用户输入,因此该循环将以其物理能力尽快执行。在我的计算机上,此循环的运行速度约为13khz。

当然,即使您要用实际工作来填充此循环,它也会尽可能快地运行,尽管一旦完成实际工作,它可能会比13khz慢,可能会比显示器的刷新率快。

如果启用垂直同步或添加故意的等待,GPU使用将更加合理

最简单的解决方案是仅启用垂直同步,这意味着GPU仅在显示器准备好以60hz(或120hz或144hz,无论显示器以什么速率运行)下一帧时才渲染。

您的帖子声明启用了垂直同步,但是您已经具有将其注释掉的功能。取消注释glfwSwapInterval(1);,即使没有需要渲染的渲染,您也应该看到GPU使用率急剧下降。如果有FPS显示屏,则应该看到FPS从原来的水平下降到相对平坦的60hz。或16.67 ms帧时间(如果您要跟踪的话)。