【问题标题】:SDL GPU Why is blitting two images in two seperates for loops way faster?SDL GPU 为什么在两个单独的 for 循环中对两个图像进行 blitting 更快?
【发布时间】:2020-09-09 13:49:48
【问题描述】:

所以我目前正在 SDL_GPU/C++ 中尝试一些东西,我有以下设置,图像分别为 32 x 32 像素,第二张图像是透明的。

    //..sdl init..//
    GPU_Image* image = GPU_LoadImage("path");
    GPU_Image* image2 = GPU_LoadImage("otherpath");
    for (int i = 0; i < screenheight; i += 32) {
        for (int j = 0; j < screenwidth; j += 32) {
           GPU_Blit(image, NULL, screen, j, i);
           GPU_Blit(image2, NULL, screen, j, i);

        }
    }

这个带有 WQHD 尺寸屏幕的代码有 ~20FPS。但是,当我执行以下操作时

   for (int i = 0; i < screenheight; i += 32) {
        for (int j = 0; j < screenwidth; j += 32) {
            GPU_Blit(image, NULL, screen, j, i);
        }
    }

    for (int i = 0; i < screenheight; i += 32) {
        for (int j = 0; j < screenwidth; j += 32) {
            GPU_Blit(image2, NULL, screen, j, i);
        }
    }

即在两个不同的 for 循环中分离两个 blitt 调用,我得到 300FPS。

有人可以尝试向我解释一下,或者知道这里可能发生了什么吗?

【问题讨论】:

  • 可能是因为引用的局部性更好,因此缓存未命中率更低。

标签: c++ gpu sdl


【解决方案1】:

虽然缓存位置可能会产生影响,但我认为这不是这里的主要问题,尤其是考虑到帧时间从 50 毫秒下降到 3.3 毫秒。

感兴趣的调用当然是GPU_Blit,它被定义为here 进行一些检查,然后调用_gpu_current_renderer-&gt;impl-&gt;Blit。这个Blit 函数似乎指的是同一个函数,无论渲染器如何。它被定义为here

其中的许多代码都使用了图像参数,但特别是两个函数,prepareToRenderImagebindTexture,如果您不渲染与上一个 blit 中相同的内容,则多次调用 FlushBlitBuffer。在我看来,这是一项昂贵的手术。我以前没有使用过 SDL_gpu,所以我不能保证任何事情,但是如果你渲染的东西不是你之前渲染的东西,它必然会产生更多的glDraw* 调用,而不是你一次又一次地渲染相同的东西。而glDraw* 调用通常是 OpenGL 应用程序中最昂贵的 API 调用。

众所周知,在 3D 图形中,尽可能少地更改上下文(在本例中是要 blit 的图像)可以提高性能,这仅仅是因为它可以更好地利用 CPU 和 GPU 之间的带宽。一个典型的例子是将使用某些特定纹理集(例如材质)的所有渲染组合在一起。在您的情况下,它将一个图像的所有渲染分组,然后对另一张图像进行分组。

【讨论】:

    【解决方案2】:

    虽然两个示例渲染相同数量的纹理,但第一个示例强制 GPU 进行数百/千(取决于屏幕大小)纹理绑定,而第二个示例仅进行 2 个纹理绑定。

    在现代 GPU 上渲染纹理的成本非常便宜,而纹理绑定(切换到使用另一个纹理)则非常昂贵。

    请注意,您可以使用纹理图集来缓解纹理绑定瓶颈,同时保持所需的渲染顺序。

    【讨论】:

      猜你喜欢
      • 2018-08-03
      • 2021-12-20
      • 2016-02-07
      • 1970-01-01
      • 2018-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-27
      相关资源
      最近更新 更多