5

假设您在 CUDA 内核中声明了一个新变量,然后在多个线程中使用它,例如:

__global__ void kernel(float* delt, float* deltb) {
int i = blockIdx.x * blockDim.x + threadIdx.x;
float a;
a = delt[i] + deltb[i];
a += 1;
}

内核调用如下所示,具有多个线程和块:

int threads = 200;
uint3 blocks = make_uint3(200,1,1);
kernel<<<blocks,threads>>>(d_delt, d_deltb);
  1. “a”是否存储在堆栈中?
  2. 初始化时是否为每个线程创建了一个新的“a”?
  3. 或者每个线程会在未知时间独立访问“a”,从而可能会弄乱算法?
4

2 回答 2

9

在内核函数中声明的任何变量(标量或数组),没有 extern 说明符,对于每个线程都是本地的,也就是说,每个线程都有自己的该变量的“副本”,线程之间不会发生数据竞争!

编译器根据编译器执行的转换和优化来选择局部变量是驻留在寄存器还是驻留在本地内存(实际上是全局内存)中。

有关哪些变量进入本地内存的更多详细信息,请参阅 NVIDIA CUDA 用户指南,第 5.3.2.2 章

于 2013-08-01T10:52:18.617 回答
8

以上都不是。CUDA 编译器足够智能且具有足够的优化能力,它可以检测到a 未使用的代码,并且可以优化掉完整的代码。您可以通过编译内核来确认这一点,-Xptxas=-v并查看资源计数,这基本上应该是没有寄存器,也没有本地内存或堆。

在一个不太简单的例子中,a可能会存储在每个线程的寄存器中,或者存储在每个线程的本地内存中,它是芯片外的 DRAM。

于 2013-07-29T20:42:22.090 回答