全局内核中的 CUDA 变量



我的问题是:

1(我是否正确理解,当您在全局内核中声明一个变量时,每个线程都会有不同的变量副本。这允许您在此变量中为每个线程存储一些中间结果。示例:向量 c=a+b:

__global__ void addKernel(int *c, const int *a, const int *b)
{
   int i = threadIdx.x;
   int p;
   p = a[i] + b[i];
   c[i] = p;
} 

这里我们声明中间变量 p。但实际上,这个变量有 N 个副本,每个副本对应每个线程。

2(如果我声明数组,将创建该数组的 N 个副本,每个副本用于每个线程,这是真的吗?只要全局内核中的所有内容都发生在 GPU 内存上,对于声明的任何变量,GPU 上的内存就需要 N 倍,其中 N 是线程数。

3(在我目前的程序中,我有35 * 48= 1680个块,每个块包含32 * 32 = 1024个线程。这是否意味着,在全局内核中声明的任何变量都将花费我 N=1024*1680=1 720 320 倍于内核外部?

4( 要使用共享内存,每个变量需要比平时多 M 倍的内存。这里 M 是数。这是真的吗?

1( 是的。每个线程都有一个在函数中声明的非共享变量的私有副本。这些通常会进入 GPU register内存,但可能会溢出到local内存中。

2(、3(和4(虽然您确实需要该专用内存的许多副本,但这并不意味着您的GPU必须同时为每个线程提供足够的专用内存。这是因为在硬件中,并非所有线程都需要同时执行。例如,如果启动 N 个线程,则可能是一半线程在给定时间处于活动状态,另一半在有空闲资源运行它们之前不会启动。

线程使用的资源越多,硬件可以同时运行的资源就越少,但这并不限制您可以要求运行的资源数量,因为一旦释放一些资源,GPU 没有资源的任何线程都将运行。

这并不意味着你应该发疯并宣布大量的本地资源。GPU 速度很快,因为它能够并行运行线程。要并行运行这些线程,它需要在任何给定时间适应大量线程。从非常一般的意义上讲,每个线程使用的资源越多,在给定时刻处于活动状态的线程就越少,硬件可以利用的并行度就越少。

最新更新