【问题标题】:Why does an empty loop use so much GPU (OpenGL)?为什么一个空循环使用这么多 GPU (OpenGL)?
【发布时间】:2019-01-13 06:42:55
【问题描述】:

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

我正在使用 glfw 并使用以下代码进行 glew:

#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 启动器占用了我大约 6-7% 的 GPU 时间,而我使用上述代码运行的程序占用了大约 13% 的 GPU 时间。

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

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

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

顺便说一句,我测试了有评论部分和没有评论部分,结果非常相似。我也尝试过使用 OpenGL 4,但完全没有影响。

为 NVIDIA 和 Intel GPU 启用了 VSync。

【问题讨论】:

  • 您应该检查您的错误返回代码。可能会给你一个提示。
  • 例如如果 glfwSwapInterval 由于某种原因失败。
  • 这是一个奇怪的分辨率(全高清的 1/4),它不应该是任何 13%,但放大到实际分辨率时会出现一些性能损失。
  • @ZanLynx 没有错误,所有功能都按预期运行。
  • “事实上,我的程序从 4% 开始,几秒钟后上升到 13%。”是的,因为 GPU 进入省电模式并降低时钟。 “GPU利用率”只是一个没有上下文的无意义数字

标签: c++ opengl mingw-w64


【解决方案1】:

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

这不是一个空循环

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

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

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

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

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

【讨论】:

  • 问题说“我已经测试了有和没有评论的部分,结果非常相似”
  • 我还从驱动程序设置中启用了垂直同步。
猜你喜欢
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-24
  • 2012-04-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多