2014-03-04 48 views
-5

我正在閱讀Sanders的書「CUDA by example」,作者提到了第441頁:例如,當我們在光線追蹤器中啓動內核時,GPU開始執行我們的代碼,但CPU繼續執行GPU完成前我們程序的下一行。 - 突出顯示2014年3月4日GPU內核運行時CPU會繼續執行下一行代碼嗎?會導致錯誤嗎?

我想知道這個說法是否正確。例如,如果下一條指令CPU繼續執行取決於GPU內核輸出的變量呢?會導致錯誤嗎?根據我的經驗,這不會導致錯誤。那麼作者究竟意味着什麼呢?

非常感謝!

回答

2

是的,作者是正確的。假設我的內核啓動如下所示:

int *h_in_data, *d_in_data, *h_out_data, *d_out_data; 
// code to allocate host and device pointers, and initialize host data 
... 
// copy host data to device 
cudaMemcpy(d_in_data, h_in_data, size_of_data, cudaMemcpyHostToDevice); 
mykernel<<<grid, block>>>(d_in_data, d_out_data); 
// some other host code happens here 
// at this point, h_out_data does not point to valid data 
... 
cudaMemcpy(h_out_data, d_out_data, size_of_data, cudaMemcpyDeviceToHost); 
//h_out_data now points to valid data 

內核啓動後,CPU繼續執行主機代碼。但是由設備生成的數據(d_out_datah_out_data)尚未準備好。如果主機代碼嘗試使用h_out_data指向的任何內容,它將只是垃圾數據。該數據僅在第二次cudaMemcpy操作後生效。

請注意,在第二個cudaMemcpy之前使用數據(h_out_data)將不會生成錯誤,如果這意味着分段錯誤或其他運行時錯誤。但是,生成的任何結果都不正確。

+0

感謝您的回答!我的後續問題是,如果我通過像這樣的簡單指令在mykernel <<<...> >>(d_in_data,d_out_data)之後交換指針(d_in_data和d_out_data):temp = d_out_data; d_out_data = d_in_data; d_in_data =溫度;這些是CPU指令。他們會搞亂GPU上的計算,因爲我的內核可能還沒有完成,但CPU繼續執行這些代碼行?提前致謝! – maximussong

+1

指針(在我的示例中,'d_in_data','d_out_data')通過* value *傳遞給設備,就像常規的C API用法指示的那樣。 (它們引用的數據由* pointer *傳遞,但指針本身由* value *傳遞)。因此,在發送到內核調用後修改指針值對內核行爲沒有影響。通過值傳遞的C函數參數具有它自己的該值的副本,該值是函數的本地(內部),與調用環境無關。 –

2

在CUDA中啓動的內核默認是異步的,即在啓動後控件將返回到CPU。現在,如果CPU的下一條指令是另一個內核啓動,那麼您不必擔心,只有在先前啓動的內核完成其執行後纔會執行此啓動。 但是,如果下一條指令只是某個正在訪問內核結果的CPU指令,則可能存在訪問垃圾值的問題。因此,必須非常小心,並在需要時進行設備同步。

+1

感謝您的回答!我的後續問題是,如果我通過像這樣的簡單指令在mykernel <<<...> >>(d_in_data,d_out_data)之後交換指針(d_in_data和d_out_data):temp = d_out_data; d_out_data = d_in_data; d_in_data =溫度;這些是CPU指令。他們會搞亂GPU上的計算,因爲我的內核可能還沒有完成,但CPU繼續執行這些代碼行?提前致謝! – maximussong

相關問題