CUDA在哪里声明共享内存分配的常量

时间:2016-12-29 23:57:02

标签: cuda constants declaration gpu-shared-memory

我正在运行1024个矩阵的适应度函数,每个矩阵都有自己的块并且大小相同。每个块都有n*n个线程(矩阵的维度),并且需要n*n共享内存,这样我才能轻松减少总和。但是,所有矩阵的维n在运行之前是可变的(即,它可以手动更改,但总是2的幂,因此求和很简单)。这里的问题是必须使用常量分配共享内存,但我还需要将值从主机传递给内核。我在哪里声明维n以便它对CPU可见(用于传递给内核)并且可以用来声明共享内存的大小(在内核中)?

我的代码结构如下:

来自main.cu我打电话给内核:

const int num_states = 1024
const int dimension = 4

fitness <<< num_states, dimension * dimension >>> (device_array_of_states, dimension, num_states, device_fitness_return);

然后在kernel.cu我有:

__global__ void fitness(
    int *numbers, 
    int dimension, 
    int num_states, 
    int *fitness_return) {
    __shared__ int fitness[16]; <<-- needs to be dimension * dimension
    //code
}

numbers是一个代表1024个矩阵的数组,dimension是行和列的长度,num_states是1024,fitness_return是一个长度为1024的数组,用于保存适应度每个矩阵的值。在内核中,共享内存使用dimension的平方进行硬编码(因此dimension在此示例中为4)。

我在哪里以及如何声明dimension以便它可以用来分配共享内存以及调用内核,这样我只需要在一个地方更新dimension?谢谢你的帮助。

1 个答案:

答案 0 :(得分:1)

分配的共享内存量在所有块上是统一的。您可能_actually_use_在每个块中使用不同数量的共享内存,但它仍然可用。此外,共享内存的数量相当有限,因此n * n个元素不能超过maximum amount of space(通常为48KiB);对于float - 类型元素(每个4个字节),这意味着n&lt; 340左右。

现在,有两种方法可以分配共享内存:静态和动态。

静态分配是您提供的示例,但不起作用:

__shared__ int fitness[16];

在这些情况下,必须在编译时知道大小(在设备端代码编译时) - 这不是你的情况。

通过动态共享内存分配,您在内核代码中指定大小 - 您leave it empty并在extern之前添加:

extern __shared__ int fitness[];

相反,你在启动内核时指定了数量,而不同块的线程并不一定知道它是什么。

但在你的情况下,线程需要知道n是什么。好吧,只需将其作为内核参数传递。所以,

__global__ void fitness(
    int *numbers, 
    int dimension, 
    int num_states, 
    int *fitness_return,
    unsigned short fitness_matrix_order /* that's your n*/) 
{
    extern __shared__ int fitness[];
    /* ... etc ... */
}

nVIDIA的Parallel-for-all博客a nice post对使用共享内存进行了更深入的介绍,该内存专门介绍了静态和动态共享内存分配。