2011-08-15 54 views
-1

我真的不明白为什么下面的代码的输出不是a和b。CUDA程序给垃圾值

#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(); 


} 

我的逻辑有什么问题?

+1

从哪里开始 - 这在普通程序中甚至没有意义。我们必须有关于指针和局部变量以及数组和字符串的聊天,看起来:-) –

+0

@kerrek:我已经准备好了。 – Programmer

+0

@kerrek:有没有办法在cuda中的全局函数中声明一个数组,使得它在函数结束后才存在 – Programmer

回答

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设备时,必须给它一个设备指针而不是主机指针,因此您必须首先设置该设备,然后将结果复制回去,但这是唯一的变化。