统一内存与固定主机内存的行为和性能比较

4

我是一名学生,目前正在编写一种使用CUDA的程序。我相信这个程序的主题与问题无关,但我必须提到,我的教授在看到我尝试创建CUDA智能指针类后建议我在我的程序中使用Unified Memory。最好将此类描述为“数组的唯一指针”,实现了RAII习语。

在查看有关统一内存的CUDA 6.0发布说明(以及CUDA 8.0引入的更新)后,我充满了疑虑,不知道是否应该转换为统一内存。

Q1:我知道CUDA统一内存正在映射GPU和CPU内存。但我们正在讨论什么类型的CPU内存?它是固定内存,可以实现更快的数据传输吗?还是标准分页系统内存?

Q2:我知道CUDA 8.0引入的更新主要是针对Pascal架构的。但是我可以期望在Maxwell架构上加速(��对于主机固定内存)吗?

Q3:尽管我只是一名学生,但我能看到NVIDIA正在努力开发统一内存。因此,人们可能认为从长远来看,使用统一内存是一个更好的主意。我是正确的吗?

Q4:每次我想访问在设备上存储的数组的单个元素时,是否真的会将整个数组复制到主机上?


2
你有没有阅读过关于统一内存的编程指南部分?很容易演示一个代码,如果使用统一内存而不是主机固定(即映射)内存来完成相同的目的,它将更快。 - Robert Crovella
@RobertCrovella,我已经阅读了那一部分,但是我没有找到任何明显的例子来支持你所说的。你是指J.3.性能调优这一节吗?我在那里没有找到除了警告不要不负责任地使用这种内存之外的任何内容。 - PatrykB
当然,在这个部分,我已经看到了一种“指定”如何使用统一内存的方法,这将带来性能上的好处,但对我来说似乎还不够。 - PatrykB
1
统一内存主要不是为了比普通的CUDA内存处理带来性能上的好处。此外,有关它使用哪种“类型”内存,在什么情况下使用的问题在那里得到了解释。 - Robert Crovella
1个回答

2

GPU内存的智能指针

你最初的动机之一是使用智能指针来管理(全局)GPU内存。你的教授建议使用统一内存实现这一点,但我不太清楚这样做有什么帮助。事实上,并不需要重新发明轮子,因为你可以在cuda-api-wrappers库中使用unique_ptr来管理(不同类型的)CUDA GPU内存。

这些独特的指针实际上就是std::unique_ptr(),但具有自定义删除程序(可以使用适当的方法来创建它们),可以在这个 doxygen 页面上找到创建它们的方法列表(虽然文档在这一点上非常不完整)。

例如,考虑CUDA示例vectorAdd,该示例对两个向量进行逐元素相加以产生第三个向量。这里是相同的示例,使用智能指针管理主机和设备内存(以及API包装器)。

注意:我是API包装器库的作者,所以我有倾向性地支持使用它 :-)

对你特定问题的(部分)回答

Q1: 我们正在讨论什么样的CPU内存[用于统一内存分配]? 是固定内存... 还是标准分页系统内存?

我不知道,但你可以通过编写一个小程序来轻松找出:

  1. 分配一些受管内存。
  2. 在主机端写入它。
  3. 将其预取到GPU上,然后退出。

...并进行性能分析以确定PCIe带宽。使用PCIe 3.0且没有干扰流量,固定内存通常会得到约12 GB/sec的速度,而非固定内存则为其一半左右。

Q2: ... 在CUDA 8.0中... 我能否期望Maxwell架构(相对于主机固定内存)的加速效果?

据我非常有限的经验,统一内存访问卡的性能在CUDA 8.0相对于CUDA 6.0没有改善。(但在预取逻辑或一般的代码优化方面可能有底层的更改,在某些情况下确实表现出了改进。)不管怎样,记住CUDA 6.0不支持sm_52目标,所以你的问题有点无用。

问题3:...我可以看到NVIDIA正在努力开发统一内存。因此,从长远来看,使用统一内存可能是一个更好的选择。我对吗?

我认为你是错的。正如CUDA编程指南所建议的那样,统一内存是一种旨在简化内存访问和编程的机制;它牺牲了一些速度以获得更加统一、简单的代码。虽然nVIDIA的努力可能会减少使用它的开销,但没有疯狂的优化措施能够消除这种开销。在Kepler Tesla上,在各种基准测试中,使用统一内存通常会慢1.8倍到2倍;即使我没有Maxwell或Pascal的数据,我也怀疑这种情况会有很大改观,以至于你会更喜欢全面使用统一内存。

问题4:当我想要访问主机上数组的单个元素(而数据驻留在设备上)时,每次都会将整个数组复制到主机上吗?

不,管理内存是分页的;因此只有一个页面会通过PCIe总线进行复制。但如果数组很小,可能是整个数组。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接