cudaMallocManaged是否在RAM和VRAM中创建同步缓冲区?

问题描述

在Nvidia开发人员博客中:An Even Easier Introduction to CUDA,作者解释:

要在GPU上进行计算,我需要分配可访问的内存 GPU。 CUDA中的统一内存通过提供单个 系统中所有GPU和cpu均可访问的内存空间。至 在统一内存中分配数据,调用['_','_','t','_'] , 返回可以从主机(cpu代码或设备访问的指针 (GPU)代码

我发现这既有趣又有趣(因为它似乎很方便):

返回一个指针,您可以从主机(cpu代码或设备访问该指针 (GPU)代码

要做到这一点,似乎cudamallocManaged()必须在VRAM和RAM上同步2个缓冲区。是这样吗还是我缺乏理解?

到目前为止,在通过GPU.js通过GPU加速WebGL抽象层之上的工作中,我了解了在内核之间传递基于VRAM的缓冲区(WebGL中的纹理)到内核之间的明显性能差异(保持缓冲区处于打开状态)高性能的GPU)并在内核之外检索缓冲区值,以通过JavaScript在RAM中访问它(将缓冲区从GPU中拉出,因为GPU上的VRAM中的缓冲区不会神奇地移动到RAM上,因此会降低性能)。

请原谅我对该主题的高度抽象的理解/描述,因为我知道大多数CUDA / C ++开发人员对该过程都有更细致的理解。

  • cudamallocManaged()也在两个RAM中创建同步缓冲区 和VRAM,以方便开发人员?
  • 如果是这样,在以下情况下,这样做会带来不必要的成本 我们可能永远不需要与cpu接触那个缓冲区?
  • 编译器是否只是检查我们是否曾经引用过该缓冲区 从cpu,并且永远不要创建同步缓冲区的cpu端 不需要吗?
  • 还是我全都错了?我们甚至不谈论VRAM吗?如何 这项工作?

解决方法

为了方便开发人员,cudaMallocManaged()是否同时在RAM和VRAM中创建同步缓冲区?

是,或多或少。 “同步”在托管内存模型中称为数据的迁移。对所有可见的处理器进行虚拟地址分割,然后将数据迁移(即移动到该物理地址并为其提供物理分配)以尝试访问它。

如果是这样,在我们可能永远不需要与CPU接触该缓冲区的情况下,这样做会不会带来不必要的成本?

如果您永远不需要触摸CPU上的缓冲区,那么将发生在CPU VA空间中进行VA分割的情况,但不会对其进行物理分配。当GPU尝试实际访问数据时,它将导致分配“显示”并耗尽GPU内存。尽管要确保有“成本”,但是在这种情况下不会占用CPU(物理)内存。此外,一旦在GPU内存中实例化,GPU访问它就不会产生额外的持续费用;它应该以“全速”运行。实例化/迁移过程是一个复杂的过程,在此我要描述的是我认为的“主要”模态或行为。有很多因素可能会影响这一点。

编译器是否只是检查我们是否曾经从CPU引用过该缓冲区,并且在不需要的情况下从不创建同步缓冲区的CPU端?

否,这是由运行时管理的,而不是由编译时管理的。

还是我全都错了?我们甚至不谈论VRAM吗?如何运作?

不,您没有错。是的,我们谈论的是VRAM。

您引用的博客几乎没有涉及托管内存,这是一个相当复杂的主题。有许多在线资源可了解更多信息。您可能需要查看其中的一些内容。 here是一个。在托管内存上有不错的GTC演示,包括here。 CUDA编程指南中还有entire section涉及托管内存。