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

bug*_*lan 0 c++ opengl mingw-w64

我正在尝试使用现代 OpenGL 创建一个 GUI 库。但我注意到,当其他游戏和程序使用了大约 16-20% 的 GPU 时间时(当游戏未启动时,在主菜单上)我简单的 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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

我的电脑有问题还是编译器/api有问题?

顺便说一下,我测试了有和没有评论部分的情况,结果非常相似。我也尝试使用 OpenGL 4 但它根本没有影响。

NVIDIA 和 Intel GPU 均启用了垂直同步。

Xir*_*ema 7

您在这个(看似)简单的程序中看到的 GPU 使用率高有几个原因,但最大的原因是……

这不是一个空循环

举个例子,一个线功能打电话你会在你的循环结束时进行:glfwSwapBuffers(window);。这是负责指示 GPU 丢弃当前渲染帧并渲染下一帧的函数调用。即使没有要绘制的实际对象,这仍然需要 GPU 重绘几百万像素(取决于您的显示器大小),并且由于您的循环只会等待用户输入,因此该循环将尽可能快地执行;在我的电脑上,这个循环本身将以大约 13khz 运行。

当然,即使你用实际工作来填充这个循环,它仍然会尽可能快地运行,虽然一旦它有实际工作要做,它可能会比 13khz 慢,但它可能会比显示器的刷新率快得多。

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

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

您的帖子声称已启用垂直同步,但您已经将执行此操作的功能注释掉了。取消注释glfwSwapInterval(1);,您应该会看到 GPU 使用率急剧下降,即使 GPU 不需要进行任何渲染。如果您有 FPS 显示器,您应该会看到 FPS 从任何时候下降到相对平坦的 60hz;或 16.67 ms 帧时间,如果那是您跟踪的内容。