【问题标题】:Vulkan buffer memory management - When do we need staging buffers?Vulkan 缓冲区内存管理 - 我们什么时候需要暂存缓冲区?
【发布时间】:2017-12-09 23:24:56
【问题描述】:

我阅读了很多关于 Vulkan 内存管理的文章,所有文章都建议使用暂存缓冲区来传输到 GPU。 但是我们已经可以创建设备本地和主机可见、主机一致的内存。它可以从 GPU 读取,也可以从 CPU 写入。

我认为这是合理的——创建一个绑定到设备本地、主机可见和连贯的内存的大缓冲区。现在对于所有动态缓冲区,我们只是继续使用此缓冲区中的内存并将缓冲区绑定到该偏移量。

但在大多数示例中,它们创建一个主机可见缓冲区和一个可见 gpu,并使用 copyBuffer 操作进行传输。与只使用一个 cpu 和 gpu 都可以访问的缓冲区相比,这样做有什么优势?我只在谈论缓冲区,而不是纹理。

【问题讨论】:

    标签: vulkan


    【解决方案1】:

    正如棘轮怪胎所说,设备不需要具有设备本地和主机可见的内存类型。尽管大多数都这样做,但大小可能是有限的。也许过去几年情况发生了变化,但过去 PCI-E 和 BIOS 的限制意味着 256 MB 或 512 MB 是你所能得到的。最后,CPU 通过 PCI-E 写入的带宽将低于 CPU 自己的内存。因此,即使使用暂存缓冲区使用两倍的总带宽,如果它可以在传输队列上异步完成,它也会最大限度地减少 CPU 和图形管道在传输上花费的时间。因此,使用暂存缓冲区是否是净胜出将取决于特定的 CPU 和 GPU 组合,以及您的应用程序正在做什么。

    但是,在移动设备或集成 GPU 等 SOC 上,使用暂存缓冲区应该很少会成功。移动 GPU 不应限制设备本地 + 主机可见的堆大小。查看vulkan.gpuinfo.org 上的几个 Windows 集成 GPU,看起来现代 Intel 集成 GPU 也没有这样的限制,但 AMD 集成 GPU 仍然存在(我只看了几个随机样本,YMMV)。

    所有这些都使得很难给出明确的“永远做 X”的建议。就个人而言,我通常会这样做:

    • 如果我只想要一个可以在任何地方工作的代码路径并且不担心性能或内存占用,请使用暂存缓冲区。这对于离散 GPU 来说可能是一个不错的选择,但对于集成/SOC GPU 来说不是最佳选择。
    • 否则,将暂存缓冲区保留为备用路径,但在有足够大的可用池时使用共享的设备本地/主机可见池。
    • 当我开始尝试获得所有最后一点性能时,然后调整上述内容,以便在我有数据显示它是净胜出时,更喜欢使用异步传输的暂存缓冲区在离散 GPU 上进行某些上传。

    【讨论】:

    • 那么动态缓冲区呢?我们是否必须每帧都进行复制操作?我会说 DMA 引擎不会像访问 256 MB 的设备本地主机可见内存一样快吗?
    • 对,不会那么快。但是,如果您关心这一点,那么您就属于我提到的第二类,如果可以的话,您可以使用共享内存。
    【解决方案2】:

    创建一个绑定到设备本地、主机可见和一致的内存的大缓冲区。

    并非所有设备都有这样的内存堆。因此,如果您想要便携,则需要考虑到这一点。

    如果您想要/必须放入缓冲区的内存不是主机可见的,那么除了使用暂存缓冲区之外别无选择。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-25
      • 1970-01-01
      • 1970-01-01
      • 2012-06-21
      • 1970-01-01
      • 2016-06-25
      相关资源
      最近更新 更多