Cuda char *变量赋值

时间:2011-07-04 02:56:26

标签: cuda nvidia

这是对此帖中所选答案的跟进问题:Output of cuda program is not what was expected

虽然以下功能有效:

__global__ void setVal(char **word)
{

    char *myWord = word[(blockIdx.y * gridDim.x) + blockIdx.x];
    myWord[0] = 'H';
    myWord[1] = 'e';
    myWord[2] = 'l';
    myWord[3] = 'l';
    myWord[4] = 'o';
}

为什么这不起作用?

__global__ void setVal(char **word)
{

    char *myWord = word[(blockIdx.y * gridDim.x) + blockIdx.x];
    myWord = "Hello\0";

}

2 个答案:

答案 0 :(得分:4)

在您的第二个版本myWord = "Hello\0";中,"Hello\0"未存储在**word参数指定的空格中。该字符串可能存储在可执行文件的.rodata部分中。赋值只是更新myWord指针 - 它不会对数据进行任何批量复制。 (虽然作为talonmies points out,编译器可以发现根本不需要指针更新,并优化掉整个函数。整洁。)

通常,C不提供内置于该语言中的任何简单的批量数据复制机制 - 设计人员认为昂贵的东西应该看起来昂贵。因此,当PL / I为多维数组中的每个元素分配0时,操作非常简单:A = 0;,C强制嵌套for()循环,内部有memset()个操作最重要的循环,让人知道这是昂贵的想法。

(将struct元素复制到函数参数是批量复制规则的唯一例外。)

答案 1 :(得分:4)

您应该开始更多地关注编译器的输出。你的第二个内核代码:

__global__ void setVal(char **word)
{
    char *myWord = word[(blockIdx.y * gridDim.x) + blockIdx.x];
    myWord = "Hello\0";
}

编译为null内核,里面没有任何内容:

$ nvcc -arch=sm_20 -c nullkernel.cu 
nullkernel.cu(3): warning: variable "myWord" was set but never used

nullkernel.cu(3): warning: variable "myWord" was set but never used

原因是因为您认为字符串复制赋值实际上只是一个指针赋值,在这种情况下编译器足够聪明,知道myWord没有写入内存,所以它只是消除了所有代码并警告你myWord没有被使用。

如果我要问一个修辞问题并以这种方式重写代码:

__global__ void setVal(char **word)
{

    char *myWord = word[(blockIdx.y * gridDim.x) + blockIdx.x];
    const char[] mymsg = "Hello\0";
    myWord = mymsg;
}

更明显的是代码为什么不编译以及它为什么永远不会“隐式”执行字符串副本赋值,即使它已经编译了?