2014-04-10 196 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