我的问题是:
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 速度很快,因为它能够并行运行线程。要并行运行这些线程,它需要在任何给定时间适应大量线程。从非常一般的意义上讲,每个线程使用的资源越多,在给定时刻处于活动状态的线程就越少,硬件可以利用的并行度就越少。