【问题标题】:Declaring Variables in a CUDA kernel在 CUDA 内核中声明变量
【发布时间】:2023-03-23 07:45:01
【问题描述】:

假设您在 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”,从而可能会弄乱算法?

【问题讨论】:

    标签: cuda


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-01-30
        • 2019-07-26
        • 2014-04-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-26
        相关资源
        最近更新 更多