我真的不明白为什么以下代码的输出不是a和b。
#include<cutil.h>
#include<iostream>
__global__ void p(unsigned char **a){
unsigned char temp[2];
temp[0] = 'a';
temp[1] = 'b';
a[0] = temp;
}
void main(){
unsigned char **a ;
cudaMalloc((void**)&a, sizeof(unsigned char*));
p<<<1,1>>>(a);
unsigned char **c;
unsigned char b[2];
cudaMemcpy(c, a, sizeof(unsigned char *), cudaMemcpyDeviceToHost);
cudaMemcpy(b, c[0], 2*sizeof(unsigned char), cudaMemcpyDeviceToHost);
for( int i=0 ; i < 2; i++){
printf("%c\n", b[i]);
}
getchar();
}
我的逻辑出了什么问题?
答案 0 :(得分:1)
现在让我们省略CUDA。让我们创建一个将数据写入用户提供的数组的函数。用户通过指针传递数组:
void fill_me_up(int * dst)
{
// We sure hope that `dst` points to a large enough area of memory!
dst[0] = 28;
dst[1] = 75;
}
现在,你正在使用局部变量做什么没有意义,因为你想使用局部变量的地址,在你离开函数范围后它变得无效。您可以做的下一个最好的事情是memcpy()
,或者一些等效的C ++算法:
void fill_me_up_again(int * dst)
{
int temp[] = { 28, 75 };
memcpy((void *)dst, (const void *)temp, sizeof(temp));
}
好的,现在要调用该函数:我们首先必须提供目标内存,然后传递一个指针:
int main()
{
int my_memory[2]; // here's our memory -- automatic local storage
fill_me_up(my_memory); // OK, array decays to pointer-to-beginning
fill_me_up(&my_memory[0]); // A bit more explicit
int * your_memory = malloc(sizeof(int) * 2); // more memory, this time dynamic
fill_me_up_again(your_memory);
/* ... */
free(your_memory);
}
(在C ++中,您可能会使用new int[2]
和delete your_memory
,但通过使用C malloc()
,可以清楚地了解与CUDA的连接。)
当你将fill_me_up
移动到CUDA设备时,你必须给它一个设备指针而不是主机指针,所以你必须首先设置它,然后将结果复制回来,但是这是唯一的改变。