2014-04-10 124 views
3

我在Stack Overflow上讀了兩篇文章,分別是Will the cublas kernel functions automatically be synchronized with the host?CUDA Dynamic Parallelizm; stream synchronization from device,他們建議在調用cuBLAS函數後使用一些同步API,例如cudaDeviceSynchronize()。我不確定使用這種通用功能是否合理。cuBLAS同步最佳實踐

按照以下方法做更好嗎? [糾正我,如果我錯了]:

cublasHandle_t cublas_handle; 
cudaStream_t stream; 
// Initialize the matrices 
CUBLAS_CALL(
    cublasDgemm(cublas_handle, CUBLAS_OP_N, CUBLAS_OP_N, M, M, 
    M, &alpha, d_A, M, d_B, M, &beta, d_C, M)); 
// cublasDgemm is non-blocking! 
cublasGetStream(cublas_handle, &stream); 
cudaStreamSynchronize(stream); 
// Now it is safe to copy the result (d_C) from the device 
// to the host and use it 

在另一方面,cudaDeviceSynchronize可以優選如果大量流/手柄被用來執行並行CUBLAS操作使用。什麼是cuBLAS手柄同步的「最佳實踐」? cuBLAS句柄可以被認爲是流的包裝器,從同步的角度來看,它們可以達到同樣的目的嗎?

+1

你不喜歡cudaDeviceSynchronize的原因是什麼?另外,在你的例子中,你沒有在cuBLAS調用之前設置流。最後,爲什麼要發揮流?對於只有一個流,將流同步pdrform不同於設備同步? – JackOLantern

回答

4

,它不會有所作爲,你是否會同步的是一個流或使用cudaDeviceSynchronize()。在性能和效果方面,它應該完全一樣。請注意,當使用事件來計算部分代碼時(例如,例如,cublas呼叫),呼叫cudaDeviceSynchronize()以獲得有意義的測量總是一個好習慣。根據我的經驗,它不會帶來任何重大的開銷,而且,使用它的內核時間更安全。

如果您的應用程序使用多個流,那麼只根據需要的流進行同步是有意義的。我相信this question會對你有所幫助。另外,您可以閱讀CUDA C編程指南,Section 3.2.5.5

2

在你的例子中你不清楚你需要使用顯式同步還是爲什麼你需要使用它。

發佈到同一個流的CUDA操作被序列化。如果啓動內核或cublas調用,然後使用cudaMemcpy操作(或cublasGetVector/Matrix等)跟隨該內核或cublas調用,則複製操作是保證不會啓動,直到所有先前的CUDA活動發出同一個流是完整的。

一般情況下的最佳做法是根本不使用顯式同步。放置必須依次依賴於相同流中的活動。在不同的流中放置彼此不依賴的活動。

有許多cuda代碼,使用cublas和其他,根本不使用顯式同步。你的例子並不特別需要它。請注意,在您鏈接的第一個答案,talonmies說:

你需要調用一個阻塞API程序如同步存儲器轉移或...

在你的榜樣,這正是你會做。您可以調用內存傳輸,發送到同一個流(例如cudaMemcpyAsync)或默認阻止傳輸(如cudaMemcpy),它會工作得很好。不需要顯式同步。

你可能希望如果您使用的是單流讀取appropriate programming guide section