我有一个需要使用全局内存的CUDA(v5.5)应用程序.理想情况下,我更喜欢使用常量内存,但我已经耗尽了常量内存,并且必须将溢出放在全局内存中.我还有一些需要偶尔编写的变量(在GPU上进行一些减少操作之后),我将它放在全局内存中.
为了阅读,我将以一种简单的方式访问全局内存.我的内核在for循环中调用,并且在内核的每次调用中,每个线程将访问完全相同的全局内存地址而没有偏移.对于写入,在每次内核调用之后,在GPU上执行缩减,并且我必须在循环的下一次迭代之前将结果写入全局存储器.但是,在我的应用程序中,除了写入全局内存之外,还有更多的读取.
我的问题是,使用动态分配的全局内存,使用全局(变量)范围中声明的全局内存是否有任何优势?我需要的全局内存量将根据应用程序而改变,因此动态分配将因此而优选.我知道我的全局内存使用的上限然而我更关心性能,所以我也可以使用一个大的固定分配静态地声明内存,我肯定不会溢出.考虑到性能,是否有理由偏好一种形式的全局内存分配而不是另一种?它们是否存在于GPU上的相同物理位置,是否以相同的方式缓存,或者两种形式的读取成本是否相同?
Rob*_*lla 10
全局内存可以静态(使用__device__),动态(使用设备malloc或new)和CUDA运行时(例如使用cudaMalloc)分配.
所有上述方法在物理上分配相同类型的存储器,即从板上(但不是片上)DRAM子系统划分出来的存储器.无论分配方式如何,此内存都具有相同的访问,合并和缓存规则(因此具有相同的一般性能注意事项).
由于动态分配需要一些非零时间,因此通过在程序开始时使用静态(ie __device__)方法或通过运行时API(即cudaMalloc等)执行一次分配,可以提高代码的性能.这避免了在代码的性能敏感区域中花时间动态分配内存.
另请注意,我概述的3种方法虽然具有与设备代码类似的类似C/C++的访问方法,但它们与主机具有不同的访问方法.使用运行时API函数访问静态分配的内存,cudaMemcpyToSymbol并且cudaMemcpyFromSymbol,运行时API分配的内存通过普通cudaMalloc/ cudaMemcpy类型函数访问,动态分配的全局内存(设备new和malloc)不能直接从主机访问.