【问题标题】:Vulkan memoryHeaps and their memoryTypesVulkan memoryHeaps 及其 memoryTypes
【发布时间】:2018-08-01 02:38:47
【问题描述】:

上图总结了我对 Vulkan 为给定系统设置生成的 memoryHeap 及其 memoryTypes 的理解。感谢@NicolBolas 123 分享的有关此主题的答案以及@krOoze 4 的答案。

不过,我还有一些 悬而未决的问题我喜欢帮助,我已将它们用红色表示,并在下面根据评论详细说明@NicolBolas。

问题

  1. 当只有 4 个 RAM 时,为什么 sysRam 中有 9 个 memoryType? 每个memoryType的物理意义是什么?如何使用每一个 这些内存类型?

  2. 为什么 GPU RAM 有 2 种内存类型?这是否意味着每个 GPU RAM的memoryType是6144MB/2 = 3072MB?

  3. 每个内存类型是否有大小限制?如果是,如何发现 他们的极限?
  4. 为什么 Vulkan 和 cat /proc/meminfo 报告的空闲内存 不一样?

提前感谢您的帮助。

【问题讨论】:

  • 请不要在图片中提出问题。如果您有问题,请将其设为真实文本。
  • @NicolBolas,我已经用真实文本提出了我的问题。
  • @NicolBolas,我早些时候将我的问题放在图片中,以便将我的问题与此事联系起来。更容易理解。谢谢。
  • 原谅我的无知...这与编程和开发有什么关系?
  • Q 1. 和 2. 是 Why does vkGetPhysicalDeviceMemoryProperties return multiple identical memory types? 和 1. 的完全重复,在那里专门回答了。问号。 2. 可能会以类似的方式工作。

标签: linux heap-memory vulkan


【解决方案1】:

当只有 4 个 RAM 时,为什么 sysRam 中有 9 个 memoryType?每个memoryType的物理意义是什么?如何使用这些 memoryType 中的每一个?

为什么 GPU RAM 有 2 种内存类型?

我不知道您所说的“4x RAM”是什么意思;我怀疑您在谈论您的机器中有多少物理记忆棒。内存类型(或堆)不关心这些事情。

至于其余部分,记住 Vulkan 中的内存是如何工作的始终很重要。堆在某种程度上代表了实际的物理 RAM。内存类型表示分配该内存的方式。但是内存的用途有自己的内存类型限制。

例如,如果图像具有颜色附件使用参数,则实现可以强制您使用特定的内存类型来支持该图像的内存。没有颜色附件的图像可以被限制为使用其他内存类型,但不是那个。以此类推。

显然,NVIDIA does this for certain combinations of usage and formats。仅仅查询可用的内存类型不足以知道如何分配内存。您必须弄清楚您将使用哪些缓冲区和图像(包括格式和使用参数)。然后你必须查询实现对它们施加了哪些限制。

您的应用程序必须适应这些限制。

每个内存类型有大小限制吗?

有这样的事情是没有意义的。 Memory types define how memory is allocated, not how much storage is available.后者是内存堆的工作。

为什么 Vulkan 和 cat /proc/meminfo 报告的空闲内存不同?

Vulkan 没有 API 来报告可用内存,只有 total 内存。询问可用内存量是愚蠢的。内存(或至少是应用程序中的虚拟页面)由应用程序中的所有线程共享。尤其是 GPU 内存在机器上的所有进程之间共享。当您得到答复时,内存量可能已经改变。因此,当您根据被告知可用的内存分配内存时,它可能不再可用。

如果发生分配失败,最好先分配并处理。

您可以询问总内存,以便决定如何分配内存块。但这就是您确定可用和不可用的方式,而不是通过查询大小。

【讨论】:

  • 为什么Vulkan报告的总内存明显小于/proc/meminfo? 26.35GB 与 32.81GB?我原以为 Vulkan 报告了空闲内存,因为 Vulkan 报告的值接近于 /proc/meminfo 中的 MemFree
  • 请原谅我的错字。我的意思是为什么 Vulkan 报告的总内存是 25.20GB 而不是 32.81GB? 7.61GB 似乎丢失了。
【解决方案2】:

[元问题] 为什么 X 在 Vulkan 中?

因为它是 Vulkan 规范所允许的。其余是实现细节,只有实现者\供应商才能确定,并且可能取决于他的睡眠情况。

  1. 当只有 4 个 RAM 时,为什么 sysRam 中有 9 个 memoryType?每个memoryType的物理意义是什么?如何使用这些 memoryType 中的每一个?

Why does vkGetPhysicalDeviceMemoryProperties return multiple identical memory types? 中回答。一个用于VkBuffers,一个用于VkImages,每个深度格式一个(即7)。等于 9;谜团解开了。

  1. 为什么 GPU RAM 有 2 种内存类型?这是否意味着 GPU RAM 的每个 memoryType 都是 6144MB/2 = 3072MB?

可能与 1 类似的原因。我推测 VkBuffers 的一个,VkImages 的一个。使用 NVIDIA 的人可以使用 vkGetXMemoryRequirements 进行测试。

它不一定意味着 RAM/2。这不是完全不可能的,但是如果是这样的话,实现者应该再次公开单独的堆。

  1. 每个内存类型是否有大小限制?如果是,如何发现它们的极限?

大约是堆大小。由于碎片化,您获得的收益可能会大大减少。并且由于其他进程共享相同。您的 impl 也可能会为自己的内部需求分配一些。

当您收到VK_ERROR_OUT_OF_DEVICE_MEMORY 时,您会发现极限。 (顺便说一句,在 CPU 端的工作方式大多与 bad_alloc 相同。

单个分配的大小有限制(不建议分配 > 4 GB),分配的数量也有限制 (maxMemoryAllocationCount)。

  1. 为什么 Vulkan 和 cat /proc/meminfo 报告的可用内存不同?

AFAIK Vulkan 不报告可用内存。 VkMemoryHeap 显示内存:

size 是堆中的总内存大小(以字节为单位)。

【讨论】:

  • Vulkan 报告的总内存为 25.20GB 而不是 32.81GB? 7.61GB 似乎丢失了。你知道为什么吗?
  • @SunBear 因为上面的 [metaanswer] - 它是允许的。似乎正好是 75%。这是一个值,通常由于碎片而分配任何东西都是有问题的(甚至不考虑其他进程以及驱动程序,您的应用程序也需要此内存)。只是一种猜测。您需要咨询 NVIDIA。
  • 相比之下,在 AMD 上,我在 8 GB RAM 的系统上得到的内存略低于 4 GB。
  • 我会写信给英伟达询问并回复你。
  • PS:docs.microsoft.com/en-us/windows-hardware/drivers/display/… 似乎暗示它将始终是 Windows 上总 RAM 的一半 +- 驱动程序施加的其他限制。
【解决方案3】:

在询问驱动程序之前,您对 Vulkan 中的内存类型一无所知。

我认为您最大的误解是内存类型在物理上是分开的。如图所示,您有两个内存堆,假设 0 是 CPU 内存,1 是 GPU。在这些堆中,您有不同的内存类型。每种内存类型占用自己的堆内空间,可以使用所有的堆空间或与其他类型共享。对于每种类型,您将有不同的内部分配方法,具有不同的对齐要求和不同的允许用途。有多个与内存类型相关的查询,包括 vkGetBufferMemoryRequirements、vkGetImageMemoryRequirements 等。这完全取决于您使用内存的目的。

此外,这些内存类型取决于驱动程序,并且会因供应商而异(看起来像当前的 nVidia 布局)。

【讨论】:

  • 是的,GPU 是 NVidia 并且使用了驱动程序 396.45,而 sys RAM 是 G.Skill。我不明白为什么 G.Skill 用propertyFlags=0 分配了 7 个 memoryTypes 而不是只分配了 1 个这样的 memoryType。感谢您指出 memoryTypes 大小与其 memoryHeap 相关的性质。
  • 我不知道 G.Skill 是什么,但它与任何内存类型都无关。您的内存类型来自所选物理设备的驱动程序,即所有这些都由 NVidia 驱动程序报告和处理。您拥有用于传输、设备内存溢出和其他用途的主机端/CPU 内存。
猜你喜欢
  • 2017-11-06
  • 2018-01-20
  • 2017-04-07
  • 2016-06-28
  • 1970-01-01
  • 2023-02-05
  • 2010-10-17
  • 1970-01-01
  • 2011-06-26
相关资源
最近更新 更多