这是对此帖中所选答案的跟进问题: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";
}
答案 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;
}
更明显的是代码为什么不编译以及它为什么永远不会“隐式”执行字符串副本赋值,即使它已经编译了?