Cuda global __device__变量自动初始化

时间:2014-01-22 16:53:16

标签: c++ cuda

我正在使用myvar说明符在设备上声明全局变量__device__。我没有在任何地方将它设置为有意义的值(在我的内核启动方法中没有像通常那样使用cudaMemcpyToSymbol)。

我希望myvar的值是随机垃圾,但每次都是0.0。 CUDA会对设备变量进行自动初始化吗?

我也使用CUDA调试器检查了它,该值实际上是0。

__device__ float myvar;

__global__ void kernel(){
    printf("my var: %f", myvar);
}

int kernel_launch(){
    kernel<<<1,5>>>();
    cudaDeviceSynchronize();
   return 0;
}

2 个答案:

答案 0 :(得分:2)

CUDA不会自动初始化任何变量。这只是一个基于CUDA实现的巧合,myvar在您的测试应用中变为零。

在IEEE-754浮点(由NVIDIA GPU使用)中,全零模式对应于0.0,因此它比“1.0f”更可能是“随机”值。

不要根据单个单词中的值来推断所有GPU内存的值...

我做了一个小实验,虽然对结果略感惊讶。我使用myvar初始化__device__ float myvar(1.1f);并更改了printf(),以便它打印变量的值和地址。然后我运行它,得到1.1f输出并记下地址。然后我删除了初始化并再次运行它。这一次,当地址保持不变时,值返回到0.0f,表明此变量所在的内存块确实在常规CUDA操作中被清零。例如,如果将CUDA程序复制到其他数据为零的固定大小的块中的GPU,并且myvar被分配给该块中的地址,则可能发生这种情况。

答案 1 :(得分:0)

__device__未初始化的变量与其全局__host__对应变量非常相似,需要在可执行文件中按其大小和位置在内存中声明。据我所知,这样的声明总是需要一个占位符值,不出所料,似乎是零。

这可以很容易地检查。例如,此命令反汇编简单__device__ int a;声明的输出:

nvcc -o test.o -c -x cu - <<< "__device__ int a;" && cuobjdump -xelf all test.o && nvdisasm *cubin

您将获得以下输出:

    .headerflags    @"EF_CUDA_TEXMODE_UNIFIED EF_CUDA_64BIT_ADDRESS EF_CUDA_SM20 EF_CUDA_PTX_SM(EF_CUDA_SM20)"


//--------------------- .nv.constant14            --------------------------
    .section    .nv.constant14,"a",@progbits
    .align  4
    .align      8
.nv.constant14:
        /*0000*/    .dword  a


//--------------------- .nv.global                --------------------------
    .section    .nv.global,"aw",@nobits
    .align  4
    .type       a,@object
    .size       a,(.L_1 - a)
a:
.nv.global:
    .zero       4
.L_1:

您可以清楚地看到隐式零初始化。

但是,我认为依靠这一点是不安全的。