2013-02-08 126 views
0

我試着搜索類似的問題,但找不到一個,雖然有一對夫婦有一個類似的標題。CUDA在相同的參數上多次調用內核函數

我對主機像這樣的代碼:

handle_error(cudaMalloc((void**)&ret_dev, FLOAT_SIZE*no_kstrings*M)); 
for(int div=0;div<no_kstrings/threads;div++){ 
    kernel<<<grid_dim,block_dim>>>(ret_dev, v_freq_vectors, &no_kstrings[threads]); 
    handle_error(cudaMemcpy(&exp_freq[threads], ret_dev, FLOAT_SIZE*threads*M, 
     cudaMemcpyDeviceToHost)); 
} 

基本上我有運行在循環中的代碼爲最大無的倍數。每塊的線程數。內核函數只是做一些事情,並將數據放入ret_dev。所以我想知道,在每次迭代之後我需要做cudaMemcpy()還是我可以在循環之外做到這一點?事情是這樣的:

handle_error(cudaMalloc((void**)&ret_dev, FLOAT_SIZE*no_kstrings*M)); 
for(int div=0;div<no_kstrings/threads;div++){ 
    kernel<<<grid_dim,block_dim>>>(ret_dev, v_freq_vectors, &no_kstrings[threads]); 
} 
handle_error(cudaMemcpy(exp_freq, ret_dev, FLOAT_SIZE*no_kstrings*M, 
    cudaMemcpyDeviceToHost)); 

我想我要問的是什麼,莫非是調用內核函數論腐敗在某種程度上這些參數相同的參數多次?

由於

+0

你是否反轉了你發佈的兩個代碼示例? – talonmies

+0

如果您正在將數據寫入'ret_dev'的相同位置,則下一次內核調用將覆蓋先前的數據。所以是的,你必須在每次迭代中複製數據。 – sgarizvi

+0

好吧,因爲我不是在'ret_dev'的同一位置上寫的,所以我不需要在每次迭代中都複製它,對吧? – vegeta

回答

0

當啓動一個內核多次(或多個內核)而沒有指定的流,它們被排隊在標準流0,並連續執行。 memcpy調用的帳戶相同。這些內核和memcpy調用的順序將被保留。此外,內核參數總是按值傳遞,稍後更改值不會破壞已安排的調用,即使它尚未啓動。

無論是否可以將memcpy移出循環,都取決於內核的功能。如果所有內核都在自己的數據塊上工作,那麼在啓動所有內核之後,您應該很好地複製結果。在這種情況下,您可能需要檢查算法是否需要全局同步,因爲如果不是,則可以通過在內核中移動for循環來獲得大量速度。

如果你的內核在所有的數據上工作,你需要在特定的時間保存它,你仍然可以考慮在gpu上分配一個額外的結果數組,並將它複製到內核中。這也應該比在循環中執行memcpy更快。