2011-08-15 73 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設備時,必須給它一個設備指針而不是主機指針,因此您必須首先設置該設備,然後將結果複製回去,但這是唯一的變化。