CudaDeviceSynchronize vs cudaThreadSynchronize vs cudaStreamSynchronize


CudaDeviceSynchronize vs cudaThreadSynchronize vs cudaStreamSynchronize

首先對這三個函數做一下解釋:

cudaDeviceSynchronize() 會阻塞當前程序的執行,直到所有任務都處理完畢(這里的任務其實就是指的是所有的線程都已經執行完了kernel function)。

cudaThreadSynchronize()的功能和cudaDeviceSynchronize()基本上一樣,這個函數在新版本的cuda中已經被“廢棄”了,不推薦使用,如果程序中真的需要做同步操作,推薦使用cudaDeviceSynchronize()。

cudaStreamSynchronize()和上面的兩個函數類似,這個函數帶有一個參數,cuda流ID,它只阻塞那些cuda流ID等於參數中指定ID的那些cuda例程,對於那些流ID不等的例程,還是異步執行的。

按照Cuda官方文檔上的解釋,cuda kernel函數是異步執行的,也就是說,kernel函數在調用之后立即把控制權交換給CPU,CPU接着往下執行。基於這樣的解釋,那么我們在編寫cuda程序時,比如:

 

kernel1<<<X,Y>>>(...);  kernel2<<<X,Y>>>(...);  cudaMemcpy(...);

 

是否應該在每一個kernel function之后加上同步的語句呢?或者說,什么時候我們應該加上同步語句呢?

其實,盡管kernel function是以異步的方式執行的,但對於同一個流內的所有cuda例程卻是順序執行的,這在官方文檔上也有說明。而在我們的cuda例程中如果不指定流ID,流ID采用缺省值,也就是說,諸如上面的代碼,不加同步語句也是可以的。當然,如果你還是不放心,加上同步語句也無所謂,無非可能需要多耗費一點同步的時間而已。

但是,當我們的程序中有多個流,並且流之間在某一點需要通信時,那就必須在這一點處加上同步的語句,即cudaDeviceSynchronize()。

 

另外說明一點,cudaMemcpy函數對於主機是同步的,但是cudaMemcpyAsyn是異步的,所以,使用 cudaMemcpyAsyn()后加  cudaDevicesynchronize() ,與單一條cudaMemcpy(),效果上是相同的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM