我正在运行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
?谢谢你的帮助。
答案 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对使用共享内存进行了更深入的介绍,该内存专门介绍了静态和动态共享内存分配。