Cuda char*变量赋值
这是本文中所选答案的后续问题: 虽然以下功能有效:Cuda char*变量赋值,cuda,nvidia,Cuda,Nvidia,这是本文中所选答案的后续问题: 虽然以下功能有效: __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'; } 为什么这不起作用 __gl
__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";
}
在第二个版本中,
myWord=“Hello\0”
,则“Hello\0”
未存储在**word
参数给定的空间中。字符串可能存储在可执行文件的.rodata
部分。赋值只是更新myWord
指针——它不进行数据的大容量复制。(尽管如此,编译器可以发现根本不需要指针更新,并优化了整个函数
一般来说,C语言不提供任何内置的简单批量数据复制机制——设计者认为昂贵的东西看起来应该很昂贵。因此,虽然PL/I使得将0
分配给多维数组中的每个元素变得非常简单:a=0代码>,C强制嵌套的for()
循环在最内部的循环中使用memset()
操作,以使人们认识到它是昂贵的
(将struct
元素复制到函数参数中是批量复制规则的唯一例外。)您应该开始更加关注编译器的输出。您的第二个内核代码:
__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;
}
更明显的是,为什么代码不编译,为什么即使它编译了也不能“隐式”执行字符串复制赋值?@Programmer:没有。那么,如何将word的particualr索引设置为字符串呢。假设我想将word[0]设置为“hello”,则将值从源字符串复制到目标字符串,就像您发布的第一个内核版本一样-即,编写自己的strcpy实现。请注意,GPU硬件在处理32位类型比8位类型要好得多,所以请考虑使用CHAR4向量类型而不是字符来在内部工作。