统一内存与固定主机内存的行为和性能
Behavior and performance of unified memory vs pinned host memory
我是一名学生,目前正在从事一个项目,该项目包括在 CUDA 中编写某个程序。我相信这个程序的主题与问题无关;但我不得不提一下,我的教授在看到我尝试创建 CUDA 智能指针 class 后,建议我在我的程序中使用统一内存。最好将此 class 描述为 "unique pointer to an array",这符合 RAII 习语。
在查看了有关统一内存的 CUDA 6.0 发行说明(以及 CUDA 8.0 中引入的更新)后,我对是否应该 统一内存充满了疑问。
Q1:我知道CUDA统一内存是映射GPU和CPU内存。但是我们在谈论什么样的 CPU 内存呢?固定内存 是否允许更快的数据传输?还是标准的分页系统内存?
Q2: 我知道 CUDA 8.0
中引入的更新主要是关于 Pascal 架构的。但是我可以期待 Maxwell 架构的加速(关于主机固定内存)吗?
Q3:虽然我只是一名学生,但我能看到NVIDIA在开发统一内存方面做了大量的工作。因此,从长远来看,人们可能会认为使用统一内存是一个更好的主意。我说得对吗?
问题 4: 每次我想访问主机上数组的单个元素(数据驻留在设备上)时,整个数组都会被复制到主机上,这是真的吗?
GPU 内存的智能指针
(部分)您最初的动机是为(全局)GPU 内存使用智能指针的可能性;你的教授建议为此使用统一内存(尽管我不太清楚这有什么帮助)。好吧,问题是,您不必为此重新发明轮子 - 作为 cuda-api-wrappers 库的一部分,您已经可以为(不同种类的)CUDA GPU 内存提供 unique_ptr
。
这些独特的指针实际上是 std::unique_ptr()
,但带有自定义删除器(您可以使用适当的方法创建它们。您可以在 this doxygen page 上找到创建它们的方法列表(尽管文档在这一点上非常片面。
有关使用示例,请考虑 CUDA 样本示例 vectorAdd, which performs elementwise addition of two vectors to produce a third. Here 是同一个样本,对主机和设备内存都使用智能指针(更普遍的是 API 包装器)。
警告:我是 API 包装器库的作者,所以我偏向于使用它:-)
(部分)回答您的具体问题
Q1: What kind of CPU memory are we talking about [for unified memory allocations]? Is it pinned memory... Or... standard paged system memory?
我不知道,但是您可以通过编写一个小程序轻松地找出答案:
- 分配一些托管内存。
- 在主机端写入。
- 将其预取到 GPU,然后退出。
... 并分析它以确定 PCIe 带宽。使用 PCIe 3.0 并且没有干预流量,我通常从固定内存中获得 ~12 GB/sec,从非固定内存中获得大约一半。
Q2: ... in CUDA 8.0 ... can I expect acceleration on the Maxwell architecture (with respect to host pinned memory)?
以我非常有限的经验,统一内存访问卡的性能在 CUDA 8.0 中相对于 CUDA 6.0 并没有提高。 (但在预取逻辑或一般代码优化方面可能存在底层变化,在某些情况下确实显示出改进。)无论如何,请记住 CUDA 6.0 不支持 sm_52 目标,所以你的问题是有点实际意义。
Q3: ... I can see that NVIDIA is putting a lot of work into developing unified memory. Therefore one might think that using unified memory is a better idea in long term perspective. Am I right?
我相信你错了。正如 CUDA 编程指南所建议的那样,统一内存是一种旨在简化内存访问和编程的机制;它牺牲了一些速度以获得更统一、更简单的代码。虽然 nVIDIA 的努力可能会在一定程度上减少使用它的开销,但没有疯狂的优化破折号可以使它消失。在 Kepler Tesla 的各种基准测试中,using unified memory is typically up to 1.8x-2x slower;即使我没有 Maxwell 或 Pascal 的数据,我怀疑这会下降到让你更喜欢全面使用统一内存的程度。
Q4: Is it true that each time I want to access single element of an array on host (while data reside on device) the whole array will be copied to host?
不,托管内存被分页;所以只有一个页面会被复制到 PCIe 总线上。但如果数组很小,它可能是整个数组。
我是一名学生,目前正在从事一个项目,该项目包括在 CUDA 中编写某个程序。我相信这个程序的主题与问题无关;但我不得不提一下,我的教授在看到我尝试创建 CUDA 智能指针 class 后,建议我在我的程序中使用统一内存。最好将此 class 描述为 "unique pointer to an array",这符合 RAII 习语。
在查看了有关统一内存的 CUDA 6.0 发行说明(以及 CUDA 8.0 中引入的更新)后,我对是否应该 统一内存充满了疑问。
Q1:我知道CUDA统一内存是映射GPU和CPU内存。但是我们在谈论什么样的 CPU 内存呢?固定内存 是否允许更快的数据传输?还是标准的分页系统内存?
Q2: 我知道 CUDA 8.0
中引入的更新主要是关于 Pascal 架构的。但是我可以期待 Maxwell 架构的加速(关于主机固定内存)吗?
Q3:虽然我只是一名学生,但我能看到NVIDIA在开发统一内存方面做了大量的工作。因此,从长远来看,人们可能会认为使用统一内存是一个更好的主意。我说得对吗?
问题 4: 每次我想访问主机上数组的单个元素(数据驻留在设备上)时,整个数组都会被复制到主机上,这是真的吗?
GPU 内存的智能指针
(部分)您最初的动机是为(全局)GPU 内存使用智能指针的可能性;你的教授建议为此使用统一内存(尽管我不太清楚这有什么帮助)。好吧,问题是,您不必为此重新发明轮子 - 作为 cuda-api-wrappers 库的一部分,您已经可以为(不同种类的)CUDA GPU 内存提供 unique_ptr
。
这些独特的指针实际上是 std::unique_ptr()
,但带有自定义删除器(您可以使用适当的方法创建它们。您可以在 this doxygen page 上找到创建它们的方法列表(尽管文档在这一点上非常片面。
有关使用示例,请考虑 CUDA 样本示例 vectorAdd, which performs elementwise addition of two vectors to produce a third. Here 是同一个样本,对主机和设备内存都使用智能指针(更普遍的是 API 包装器)。
警告:我是 API 包装器库的作者,所以我偏向于使用它:-)
(部分)回答您的具体问题
Q1: What kind of CPU memory are we talking about [for unified memory allocations]? Is it pinned memory... Or... standard paged system memory?
我不知道,但是您可以通过编写一个小程序轻松地找出答案:
- 分配一些托管内存。
- 在主机端写入。
- 将其预取到 GPU,然后退出。
... 并分析它以确定 PCIe 带宽。使用 PCIe 3.0 并且没有干预流量,我通常从固定内存中获得 ~12 GB/sec,从非固定内存中获得大约一半。
Q2: ... in CUDA 8.0 ... can I expect acceleration on the Maxwell architecture (with respect to host pinned memory)?
以我非常有限的经验,统一内存访问卡的性能在 CUDA 8.0 中相对于 CUDA 6.0 并没有提高。 (但在预取逻辑或一般代码优化方面可能存在底层变化,在某些情况下确实显示出改进。)无论如何,请记住 CUDA 6.0 不支持 sm_52 目标,所以你的问题是有点实际意义。
Q3: ... I can see that NVIDIA is putting a lot of work into developing unified memory. Therefore one might think that using unified memory is a better idea in long term perspective. Am I right?
我相信你错了。正如 CUDA 编程指南所建议的那样,统一内存是一种旨在简化内存访问和编程的机制;它牺牲了一些速度以获得更统一、更简单的代码。虽然 nVIDIA 的努力可能会在一定程度上减少使用它的开销,但没有疯狂的优化破折号可以使它消失。在 Kepler Tesla 的各种基准测试中,using unified memory is typically up to 1.8x-2x slower;即使我没有 Maxwell 或 Pascal 的数据,我怀疑这会下降到让你更喜欢全面使用统一内存的程度。
Q4: Is it true that each time I want to access single element of an array on host (while data reside on device) the whole array will be copied to host?
不,托管内存被分页;所以只有一个页面会被复制到 PCIe 总线上。但如果数组很小,它可能是整个数组。