在CUDA中使用常量

时间:2013-04-20 11:41:56

标签: c cuda const nvidia

在CUDA中使用常量的最佳方法是什么?

一种方法是在常量内存中定义常量,例如:

// CUDA global constants
__constant__ int M;

int main(void)
{
    ...
    cudaMemcpyToSymbol("M", &M, sizeof(M));
    ...
}

一种替代方法是使用C预处理器:

#define M = ... 

我认为使用C预处理器定义常量要快得多。那么在CUDA设备上使用常量内存有什么好处呢?

2 个答案:

答案 0 :(得分:12)

  1. 编译时已知的常量应使用 预处理器宏(例如#define)或通过全局/文件范围的C / C ++ const变量。
  2. 使用__constant__ memory对于使用某些值的程序可能是有益的,这些值在内核持续时间内不会发生变化,并且存在某些访问模式(例如,所有线程同时访问相同的值) )。这并不比满足上述第1项要求的常数更好或更快。
  3. 如果程序选择的数量相对较少,并且这些选择会影响内核执行,那么额外编译时优化的一种可能方法是使用templated code/kernels

答案 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缓存级别速度,至少可以说它们是非常方便的。