【问题标题】:Does cudaMallocManaged() create a synchronized buffer in RAM and VRAM?cudaMallocManaged() 是否在 RAM 和 VRAM 中创建同步缓冲区?
【发布时间】:2020-09-16 14:57:25
【问题描述】:

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

要在 GPU 上进行计算,我需要分配可由 显卡。 CUDA 中的统一内存通过提供单个 系统中所有 GPU 和 CPU 可访问的内存空间。到 在统一内存中分配数据,调用cudaMallocManaged(),即 返回可以从主机 (CPU) 代码或设备访问的指针 (GPU) 代码。

我发现这既有趣(因为它看起来可能很方便)又令人困惑:

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

要做到这一点,cudaMallocManaged() 似乎必须在 VRAM 和 RAM 之间同步 2 个缓冲区。是这样吗?还是我的理解不够?

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

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

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

【问题讨论】:

  • @RobertCrovella 谢谢!啊哈,所以它在 RAM 和 VRAM 之间复制的,但是您实际上可以对如何完成进行一些控制。

标签: c++ cuda


【解决方案1】:

那么 cudaMallocManaged() 是否会在 RAM 和 VRAM 中创建同步缓冲区以方便开发人员?

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

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

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

编译器是否可能只是检查我们是否曾经从 CPU 引用该缓冲区,并且如果不需要,则永远不会创建同步缓冲区的 CPU 端?

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

还是我全都错了?我们甚至不是在谈论 VRAM 吗?这是如何工作的?

不,你没有错。是的,我们正在谈论 VRAM。

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

【讨论】:

  • 编译时实现不是更高效吗?您解释说:“当 GPU 尝试实际访问数据时,它会导致分配‘出现’”——但据我了解,要将该缓冲区的内容从 RAM 或 CPU 填充到 VRAM 中,这会耗费时间和当数据从 RAM 通过 PCIe 移动到 VRAM 时的内存带宽,因此要么它已经存在,在分配后立即传输,要么当 GPU 尝试访问它时,数据传输存在延迟。我很惊讶这么低级别的系统会尝试进行这样的“优化”
  • 您假设这样的事情在编译时很容易(由编译器)发现。并非总是/通常情况如此。托管内存不能完美地处理所有可能的情况。但是有很多方法可以优化其行为,其中一些在this blog 中有介绍。是的,托管内存的幼稚使用会导致性能问题,请参阅here
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-24
  • 2015-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-23
  • 1970-01-01
相关资源
最近更新 更多