如何使用常量内存将结构数组传递给CUDA内核

时间:2014-11-25 09:21:52

标签: cuda

我的内核需要Configuration的列表/数组作为输入参数。我甚至有一个这样的列表/数组的列表/数组,其中一个是传递给内核。这些配置是在主机上准备的,不会更改。因此,这将是恒定内存的完美用途。但老实说,我真的不知道怎么做。

我尝试在下面的代码草案中提出我的想法。基本上,我看到了如何定义/传递列表的两种方法:

  • 将它们定义为具有固定长度的数组,并将它们按值传递给内核
  • 将它们定义为指针并只传递指向内核的指针(当然必须先复制到设备上)

我应该采用哪种方法,如何修改下面的代码以确保使用常量内存?

我希望每个列表的大小通常小于200-300字节。如果我要制作相同大小的所有列表,我可能会选择512字节或1 kB的大小。

class Configuration{
  // some constants
}

// We need a list of lists Configurations, these could be implemented either as...
Configuration a[10][100]; // fixed-length array or...
Configuration ** b; // as a dynamic array to pointers of arrays

// Parameter will take an array of Configuration, either as a pointer or directly as an array
__global__ kernel(Configuration * config){

}

// According to the above example, we use the pointer-version. Could also be a call directly using a[i]
kernel<<...>>(b[i], lengthOfB[i]);

1 个答案:

答案 0 :(得分:1)

如果您希望数据位于__constant__内存中(这可能不是智能移动,取决于您如何访问内核中的数据),那么第一种方法(固定长度数组)是唯一的明智的一个。同样为了简单起见,我将二维数组展平为一维数组,以便于使用/复制。

除了是只读之外,还要访问__constant__内存以提高效率,使得warp中的每个线程都请求相同的值。您的问题没有提到这一点,因此您可能需要参考this question/answer以获取解释/示例。

如果你使用指针方法,只有指针会在常量内存中(大概),所以这不是你想要的(大概)。

如果使用__constant__内存,则无需将该指针作为内核参数传递。数据声明具有全局范围。

这样的事可能有用:

class Configuration{
  // some constants
  int cdata;
}

__constant__ Configuration const_data[10*100];

// ***setup in host code
Configuration h_data[10*100];
// fill in h_data ...
// then copy to device
cudaMemcpyToSymbol(const_data, h_data, sizeof(h_data));
// ***

//use in kernel code
__global__ void mykernel(){

  int my_data = const_data[5].cdata;

}

请注意,总共__constant__内存限制为64K字节。