2017-05-19 62 views
1

我對CUDA來說很新,我對於對象的內存管理有個疑問。我有一個對象函數來將數據加載到設備,並且如果調用另一個對象函數,則執行計算。cuda設備變量在不同功能中的分配和使用

我已經閱讀了NVIDIA編程指南的一些部分和一些SO問題,但他們在單個函數中執行數據複製和計算,因此不需要多個函數。

更多規格: 數據只讀一次。我不知道編譯時的數據大小,因此我需要動態分配。我目前的設備的計算能力爲2.1(即將更新至6.1)。

我想複製第一個函數中的數據並在不同的函數中使用這些數據。例如:

__constant__ int dev_size; 
__device__ float* dev_data; //<- not sure about this 

/* kernel */ 
__global__ void computeSomething(float* dev_output) 
{ 
    int idx = blockIdx.x * blockDim.x + threadIdx.x; 
    if (idx < dev_size) 
    { 
     dev_output[idx] = dev_data[idx]*100; // some computation; 
    } 
} 

// function 1 
void OBJECT::copyVolumeToGPU(int size, float* data) 
{ 
    cudaMalloc(&dev_data, size * sizeof(float)); 
    cudaMemcpy(dev_data, data, size * sizeof(float), cudaMemcpyHostToDevice); 
    cudaMemcpyToSymbol(dev_size, size, sizeof(int)); 
} 

// function 2 
void OBJECT::computeSmthOnDevice(int size) 
{ 
    // allocate output array 
    auto host_output = new float[size]; 
    float* dev_output; 
    cudaMalloc(&dev_output, size * sizeof(float)); 

    int block = 256; 
    int grid = ceil(size/block); 
    computeSomething<<<grid,block>>>(dev_output); 

    cudaMemcpy(host_output, dev_data, size * sizeof(float), cudaMemcpyDeviceToHost); 

    /* ... do something with output ... */ 

    delete[] host_output; 
    cudaFree(dev_output); 
} 

gpuErrChk進行這樣:https://stackoverflow.com/a/14038590/3921660但在本例中省略。

我可以使用__device__指針(如__device__ float* dev_data;)複製數據嗎?

+0

你能試着勾畫出你在代碼中的意思嗎?因爲要理解你在這裏要問的東西並不是很容易理解。 – talonmies

+0

歡迎來到SO。請閱讀此[如何問](http://stackoverflow.com/help/how-to-ask)以改善您的問題。 – thewaywewere

回答

2

一般情況下,你的想法是可行的,但這樣的:

cudaMalloc(&dev_data, size * sizeof(float)); 

是不合法的。在主機代碼中輸入__device__項目的地址是不合法的。所以如果你知道編譯時的大小,最簡單的方法就是將它轉換爲靜態分配,例如

__device__ float dev_data[1000]; 

如果你真的想使這是一個動態分配的__device__指針,那麼你需要使用一個方法,如描述here,其中包括在主機代碼典型的設備指針是「臨時使用cudaMalloc 「,然後通過cudaMemcpyToSymbol將該」臨時「指針複製到__device__指針。然後,當您想要通過cudaMemcpy將數據複製到特定分配中時,您可以使用cudaMemcpy往/從臨時來自主機代碼的指針。

請注意,爲了將數據從一個函數傳遞到另一個函數或將一個內核傳遞到下一個目的,沒有理由不能只使用來自cudaMemcpy的動態分配的指針,並將該指針傳遞給無論你需要它。您甚至可以通過全局變量將它傳遞給任何需要它的主機函數,如普通的全局指針。但是,對於內核,您仍然需要通過內核參數將這樣一個全局指針傳遞給內核。

+0

我正在嘗試實施您的建議。你能解釋你最後一句話嗎?我沒有通過「通過命令行參數傳遞」得到你的意思。 – KabCode

+0

對不起,這是一個不好的選擇。我編輯過。只是想明確地將指針作爲參數傳遞給內核。 –