在CUDA中使用常量的最佳方法是什么?
一种方法是在常量内存中定义常量,例如:
// CUDA global constants
__constant__ int M;
int main(void)
{
...
cudaMemcpyToSymbol("M", &M, sizeof(M));
...
}
一种替代方法是使用C预处理器:
#define M = ...
我认为使用C预处理器定义常量要快得多。那么在CUDA设备上使用常量内存有什么好处呢?
答案 0 :(得分:12)
#define
)或通过全局/文件范围的C / C ++ const
变量。__constant__
memory对于使用某些值的程序可能是有益的,这些值在内核持续时间内不会发生变化,并且存在某些访问模式(例如,所有线程同时访问相同的值) )。这并不比满足上述第1项要求的常数更好或更快。答案 1 :(得分:6)
常规C / C ++样式常量:在CUDA C(本身是C99的修改)中,常量是绝对编译时实体。考虑到GPU处理的性质,鉴于NVCC中发生的优化量非常复杂,这并不奇怪。
#define
:宏总是非常不优雅,但却很有用。
__constant__
变量说明符是一种全新的动物,在我看来有些用词不当。我将在下面的空白处记下Nvidia here的内容:
__constant__
限定符,可选择与之一起使用__device__
,声明一个变量:
- 驻留在恒定的内存空间中,
- 具有应用程序的生命周期,
- 可以从网格中的所有线程访问,也可以通过运行时库从主机访问(cudaGetSymbolAddress()/ cudaGetSymbolSize()/ cudaMemcpyToSymbol()/ cudaMemcpyFromSymbol())。
Nvidia的文档指定__constant__
可用注册级别速度(接近零延迟),前提是它是由warp的所有线程访问的相同常量。
它们在CUDA代码中声明为全局范围。然而,基于个人(以及当前正在进行的)经验,在单独编译时必须小心使用此说明符,例如通过在C中放置包装函数将CUDA代码(.cu和.cuh文件)与C / C ++代码分离。式标题。
与传统"常数"不同。然而,这些变量在运行时从主机代码初始化,主机代码分配设备内存并最终启动内核。我再说一遍,我目前正在使用代码,在内核执行之前使用cudaMemcpyToSymbol()演示这些可以在运行时设置。
对于保证访问的L1缓存级别速度,至少可以说它们是非常方便的。