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向量类型而不是字符来在内部工作。