CUDA - 统一内存(至少是 Pascal)

CUDA - Unified memory (Pascal at least)

我想了解一下统一内存、它的真正工作原理以及如何有效地使用它。

据我所知,我们使用cudaMallocManaged(ptr, size);来分配统一内存数组。由于 Pascal 架构,可以将大小设置为大于 GPU 上可用的物理内存。

假设我现在有一个 GC,4GB RAM,主机 32GB RAM 和一个 1TB 的文件。我想解决这个 1TB 的文件,我该如何处理?

如果我理解的好,我可以把文件放在统一内存中,但是这个统一数组和文件之间的link是如何进行的呢?这是否意味着我必须 memcpy 我用 cudaMallocManaged 分配的指针中的整个文件?

最后,请告诉我我是否正确。如果 GPU 引发未命中,CPU 将发送它存储在其 RAM 中的数据,如果不是从磁盘发送的话。它有点简化,但如果它像这样工作,则意味着数据需要在统一数组中。

感谢您的帮助。

我的回答假设您是 运行 CUDA 9.x 或更高版本,Pascal 或 Volta GPU,在 Linux。

您将能够超额订阅 GPU 内存,最大约为主机内存的大小(即主机操作系统允许您分配的任何内存),减去任何内存分配过程中常见的合理数量(您应该不要期望分配主机内存的每个最后一个字节,同样不应该尝试对托管内存分配做同样的事情。

统一内存和文件或存储在磁盘上的任何东西之间没有link。

正如您可能无法将整个 1TB 文件加载到 32GB RAM 中一样,您也无法使用托管内存一次访问所有文件。主机操作系统允许您 allocate/load 的大小就是 GPU 可用的大小。

因此,为了处理这个 1TB 的文件,您可能需要想出一种算法,将其分解成适合系统 RAM 的部分。这个概念完全独立于托管内存。此后,如果您想使用 CUDA 访问系统 RAM 中的文件部分,您可以使用托管内存,包括超额订阅,如果您愿意的话。

将文件分成几部分的确切过程将取决于您正在进行的处理类型,并且对 CUDA 没有特别的依赖性。

在某些系统上可以超额订阅 CPU 内存。在NVLink上使用Power 9 + V100,可以使用操作系统的地址转换服务(ATS),如here.

这样一来,即使主机系统上的 RAM 数量少得多,也可以使用来自 GPU 的 1TB 数据。要做的操作如下:

  1. 创建一个文件 - 用于备份 1TB 数据 - 您只需要一个可以 mmapped 的文件描述符。
  2. 使用mmap将整个文件映射到虚拟地址space(实验系统限制为49位,即512TB)。
  3. 将该指针传递给您的内核调用。

实际情况是操作系统分页机制将按需分页调出文件块,而 GPU 将依赖 ATS 进行此操作。

在 x86_64 and/or 上一代 GPU,and/or PCI-Express 连接系统上没有提及,也没有成功测试。