2011-07-04 69 views
2

这是此帖子中所选答案的后续问题:Output of cuda program is not what was expectedCuda char *变量赋值

虽然下面的功能原理:

__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"; 

} 

回答

4

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

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

编译成什么也没有空内核里面:

$ 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; 
} 

会更明显既为什么代码不能编译,为什么它不可能“隐含”执行字符串复制分配即使它编译?

+0

那么,我如何设置一个词的一个particualr索引到一个字符串。假设我要将word [0]设置为“hello” – Programmer

+0

将源字符串中的值复制到目标字符串,就像您发布的第一个内核版本 - 即。编写你自己的strcpy实现。请注意,GPU硬件在处理32位类型时比8位类型好得多,所以考虑使用char4向量类型而不是char来使其工作。 – talonmies

4

在你的第二个版本,myWord = "Hello\0";,该"Hello\0"不是存储在由**word参数给出的空间。该字符串可能存储在可执行文件的.rodata部分。该任务只更新myWord指针 - 它不执行任何批量数据复制。 (虽然作为talonmies points out,编译器可以根本不需要指针更新,并优化了整个函数。)

通常,C不提供任何简单的批量数据复制机制内置语言 - 设计者认为昂贵的东西应该看起来昂贵。因此,虽然PL/I为多维数组中的每个元素指定0非常简单:A = 0;,C强制在最内部循环中嵌套for()循环,并使用memset()操作,以推动其成本高昂的想法。

(复制struct元素融入函数参数是唯一的例外,以批量复制的规则。)

+0

cuda中是否有strcpy? – Programmer

+1

@程序员:没有没有。 – talonmies