我有几个关于CUDA共享内存的问题。
首先,as mentioned in this post,共享内存可能以两种不同的方式声明:
分配动态共享内存,如下所示
// Lunch the kernel
dynamicReverse<<<1, n, n*sizeof(int)>>>(d_d, n);
这可能会在内核中使用,如提及:
extern __shared__ int s[];
或静态共享内存,可以在内核调用中使用如下:
__shared__ int s[64];
两者都是出于不同的原因使用,但哪一个更好,为什么?
其次,我正在运行一个多块,每块内核256个线程。我在全局和设备内核中使用静态共享内存,它们都使用共享内存。给出了一个例子:
__global__ void startKernel(float* p_d_array)
{
__shared double matA[3*3];
float a1 =0 ;
float a2 = 0;
float a3 = 0;
float b = p_d_array[threadidx.x];
a1 += reduce( b, threadidx.x);
a2 += reduce( b, threadidx.x);
a3 += reduce( b, threadidx.x);
// continue...
}
__device__ reduce ( float data , unsigned int tid)
{
__shared__ float data[256];
// do reduce ...
}
我想知道在这种情况下如何分配共享内存。我假设每个块都有自己的共享内存。
块#0进入reduce功能时会发生什么?
共享内存是否已预先分配给函数调用?
我调用三个不同的reduce设备函数,在这种情况下,理论上在块#0中,线程#[0,127]仍然可以在第一个reduce调用上执行(“由于硬字延迟”),而线程#[128,255]可能在第二次减少呼叫时进行操作。在这种情况下,我想知道两个reduce函数是否都使用相同的共享内存?
即使是从两个不同的函数调用中调用它们吗?
另一方面,单个块可能为两个函数调用分配了3 * 256 * sizeof(float)共享内存吗?这在CUDA方式中似乎是多余的,但我仍然想知道CUDA在这种情况下如何运作。
第三,由于使用
进行编译器优化,可以在共享内存中获得更高的性能 const float* p_shared ;
数据分配部分后的或限制关键字?
答案 0 :(得分:2)
AFAIR,无论是“动态地”还是“静态地”请求共享内存都没有什么区别 - 在任何一种情况下,它只是一个内核启动参数,可以由您的代码或编译器生成的代码设置。
Re:第二,编译器将对内核函数和内核调用的函数的共享内存需求求和。