GPU内存的智能指针
你最初的动机之一是使用智能指针来管理(全局)GPU内存。你的教授建议使用统一内存实现这一点,但我不太清楚这样做有什么帮助。事实上,并不需要重新发明轮子,因为你可以在cuda-api-wrappers库中使用unique_ptr
来管理(不同类型的)CUDA GPU内存。
这些独特的指针实际上就是std::unique_ptr()
,但具有自定义删除程序(可以使用适当的方法来创建它们),可以在这个 doxygen 页面上找到创建它们的方法列表(虽然文档在这一点上非常不完整)。
例如,考虑CUDA示例vectorAdd,该示例对两个向量进行逐元素相加以产生第三个向量。这里是相同的示例,使用智能指针管理主机和设备内存(以及API包装器)。
注意:我是API包装器库的作者,所以我有倾向性地支持使用它 :-)
对你特定问题的(部分)回答
Q1: 我们正在讨论什么样的CPU内存[用于统一内存分配]? 是固定内存... 还是标准分页系统内存?
我不知道,但你可以通过编写一个小程序来轻松找出:
- 分配一些受管内存。
- 在主机端写入它。
- 将其预取到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总线进行复制。但如果数组很小,可能是整个数组。