2012-03-29 69 views
2

我想知道是否當我調用cudaMemcpy(...)獲取GPU上的內存時,數組中的值是否被複制。我將更好地解釋:我將一個數組的值複製到另一個數組,然後調用cudaMalloc和cudaMemcpy。cudaMemcpy後數組的值

// Copying values of the arrays 
for(int i = 0; i<16; i++){ 
    array_device_1[i] = array_host_1[i]; 
    array_device_2[i] = array_host_2[i]; 
} 

// Memory allocation of array_device_1 and array_device_2 
cudaMalloc((void**) &array_device_1, SIZE_INT*size); 
cudaMalloc((void**) &array_device_2, SIZE_INT*size); 

// Transfer array_device_1 and array_device_2 
cudaMemcpy(array_device_1, array_host_1, SIZE_INT*size, cudaMemcpyHostToDevice); 
cudaMemcpy(array_device_2, array_host_2, SIZE_INT*size, cudaMemcpyHostToDevice); 

kernel<<<N, N>>>(array_device_1, array_device_2); 

cudaMemcpy(array_host_1, array_device_1, SIZE_INT*size, cudaMemcpyDeviceToHost); 
cudaMemcpy(array_host_2, array_device_2, SIZE_INT*size, cudaMemcpyDeviceToHost); 

cudaFree(array_device_1); 
cudaFree(array_device_2); 

所以,當我執行所有這些說明,我使用內核裏面所有的陣列,是array_device_1裏面的價值觀和array_device_2與否?我試圖打印出內核後,我發現所有的數組都是空的!真的,我不明白我如何保持它們中的值,然後用內核函數改變它們的值。

+1

你'//複製arrays'部分的值不作任何感。您不能從主機的數據複製到設備內存這種方式,那就是'cudaMemcpy'是有! – leftaroundabout 2012-03-29 15:51:12

回答

4

是的,他們有他們的價值觀。但是你不能在主機上打印出來。爲此,您需要使用回

cudaMemcpy((void *) array_host_2, (void *) array_device_2, SIZE_INT*size, cudaMemcpyDeviceToHost); 

來複制數據,然後你可以打印的array_host_2值。

更多的解釋:您的array_device_*住在GPU上,並從您的CPU(即打印您的輸出)您沒有直接訪問此數據。因此,在打印出來之前,您需要首先將其複製回CPU內存。

+0

我測試了我的內核,而不利用GPU的一部分,我的意思是我測試的算法,它工作正常。我真的無法解釋我錯過了什麼 – davideberdin 2012-03-29 16:11:18

1

的代碼片段您提供爲leftaroundabout指出似乎是正確的,除了前幾行。你確定內核是正確的嗎?也許你不會將修改過的值寫回全局內存。如果在運行內核之前製作另一組主機陣列並複製GPU陣列,它們是否正確?根據你的具體情況,array_host_ *中的值應該被正確地複製到array_device_ *。

1

複製陣列數據的裝置,改變在內核值的實施例,複製回主機和打印的新值:

// Function to run on device by many threads 
__global__ void myKernel(int *d_arr) { 
    int idx = blockIdx.x * blockDim.x + threadIdx.x; 
    d_arr[idx] = d_arr[idx]*2; 
} 

int main(void) { 
    int *h_arr, *d_arr; 
    h_arr = (int *)malloc(10*sizeof(int)); 
    for (int i=0; i<10; ++i) 
     h_arr[i] = i; // Or other values 

    // Sends data to device 
    cudaMalloc((void**) &d_arr, 10*sizeof(int)); 
    cudaMemcpy(d_arr, h_arr, 10*sizeof(int), cudaMemcpyHostToDevice); 

    // Runs kernel on device 
    myKernel<<< 2, 5 >>>(d_arr); 

    // Retrieves data from device 
    cudaMemcpy(h_arr, d_arr, 10*sizeof(int), cudaMemcpyDeviceToHost); 

    for (int i = 0; i<10; ++i) 
     printf("Post kernel value in h_arr[%d] is: %d\n", i,h_arr[i]); 

    cudaFree(d_arr); 
    free(h_arr); 
    return 0; 
}