GPU 内存的智能指针
(部分)您最初的动机是为(全局)GPU 内存使用智能指针的可能性;并且您的教授建议为此使用统一记忆(尽管我并不完全清楚这将有何帮助)。好吧,问题是,您不必为此重新发明轮子 -unique_ptr
作为cuda-api-wrappers库的一部分,您已经可以拥有(不同种类的)CUDA GPU 内存。
这些唯一的指针实际上是std::unique_ptr()
,但是使用自定义删除器(并且您使用适当的方法创建它们。您可以在此 doxygen 页面上找到用于创建它们的方法列表(尽管此时文档非常部分)。
对于使用示例,请考虑 CUDA 示例示例vectorAdd,它执行两个向量的元素相加以产生第三个。这是相同的示例,对主机和设备内存使用智能指针(以及更普遍的 API 包装器)。
警告:我是 API 包装库的作者,所以我倾向于使用它 :-)
(部分)回答您的具体问题
Q1:我们在谈论什么类型的 CPU 内存 [用于统一内存分配]?它是固定内存......还是......标准分页系统内存?
我不知道,但是您可以通过编写一个小程序轻松找出:
- 分配一些托管内存。
- 在主机端写入它。
- 将其预取到 GPU,然后退出。
...并对其进行分析以确定 PCIe 带宽。使用 PCIe 3.0 并且没有干预流量,我通常从固定内存获得约 12 GB/秒,从未固定内存获得大约一半。
Q2:……在 CUDA 8.0 中……我可以期待 Maxwell 架构的加速(相对于主机固定内存)吗?
在我非常有限的经验中,统一内存访问卡的性能在 CUDA 8.0 中相对于 CUDA 6.0 并没有提高。(但在某些情况下,预取逻辑或一般代码优化可能会有所改进。)无论如何,请记住 CUDA 6.0 不支持 sm_52 目标,因此您的问题有点没有实际意义。
Q3:...我可以看到英伟达在开发统一内存方面投入了大量工作。因此,从长远来看,人们可能会认为使用统一内存是一个更好的主意。我对吗?
我相信你错了。正如 CUDA 编程指南所建议的,统一内存是一种旨在简化内存访问和编程的机制。它牺牲了一些速度以获得更统一、更简单的代码。虽然 nVIDIA 的努力可能会在一定程度上减少使用它的开销,但没有疯狂的优化破折号可以让这种情况消失。在 Kepler Tesla 上,在各种基准测试中,使用统一内存通常会慢 1.8-2 倍;即使我没有 Maxwell 或 Pascal 的数据,我怀疑这会下降太多,以至于让您更喜欢全面使用统一内存。
Q4:是否每次我想访问主机上数组的单个元素(而数据驻留在设备上)时,整个数组都会被复制到主机上?
不,托管内存是分页的;所以只有一个页面会通过 PCIe 总线被复制。但如果数组很小,它可能是整个数组。