2016-01-22 34 views
0

說我有一個函數,它需要一個設備指針並對它執行一些操作。然而這個工作更適合cpu,所以我在cpu上分配了一塊內存,在cpu內存上執行一些操作,然後將它複製到gpu。事情是這樣的:執行主機端malloc和異步主機到設備memcpy的典型方法

void func(void *dev_ptr, cudaStream_t stream) 
{ 
    void *host_ptr = malloc(100); 
    // do something on host_ptr 
    cudaMemcpyAsync(dev_ptr, host_ptr, 100, cudaMemcpyHostToDevice, stream); 
    free(host_ptr); 
} 

free調用是這裏危險,因爲memcpy的是異步複製可能不會在該點free被稱爲完成。我弄清楚,存在CUDA回調機制,所以我覺得下面的代碼可能更合適:

void CUDART_CB callback_free(cudaStream_t, cudaError_t, void *userData) 
{ 
    free(userData); 
} 

void func(void *dev_ptr, cudaStream_t stream) 
{ 
    void *host_ptr = malloc(100); 
    // do something on host_ptr 
    cudaMemcpyAsync(dev_ptr, host_ptr, 100, cudaMemcpyHostToDevice, stream); 
    cudaStreamAddCallback(stream, callback_free, static_cast<void *>(host_ptr), 0); 
} 

問:

  1. 是它的規範的方法來完成這個任務?
  2. 如果我想host_ptr分配在堆棧而不是堆上怎麼辦?我不想在這裏介紹不必要的cudaStreamSynchronize

在此先感謝。

+1

爲什麼你甚至在C++中使用'malloc'和'free'? –

+0

@AngryLettuce沒關係......只是爲了與'cudaMalloc'和'cudaFree'一致 –

回答

4

回答您的問題:

  1. 是它的規範的方法來完成這個任務?
    據我所知,這是唯一能夠在沒有顯式同步調用的情況下做到這一點的方法。

  2. 如果我想host_ptr分配在堆棧而不是堆上怎麼辦?我不想在這裏介紹不必要的cudaStreamSynchronize
    你不會介紹一個不必要的cudaStreamSynchronize電話,你會介紹一個必要的。在這種情況下停止堆棧變量超出範圍的唯一方法是阻止,並且阻止的正確方法是調用cudaStreamSynchronize