cuBLAS同步最佳实践

时间:2014-04-10 12:56:11

标签: c cuda cublas

我在Stack Overflow上阅读了两篇帖子,即Will the cublas kernel functions automatically be synchronized with the host?CUDA Dynamic Parallelizm; stream synchronization from device,他们建议在调用cuBLAS函数后使用一些同步API,例如cudaDeviceSynchronize()。我不确定使用这样的通用功能是否合理。

按照以下方式做得更好吗? [纠正我,如果我错了]:

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

另一方面,如果使用大量流/句柄来执行并行cuBLAS操作,则可以优选使用cudaDeviceSynchronize。什么是最佳实践"用于同步cuBLAS句柄? cuBLAS句柄可以被认为是流的包装器,从同步的角度看它们是否起到同样的作用?

2 个答案:

答案 0 :(得分:4)

如果您使用的是单个流,那么无论您是要同步该流还是使用cudaDeviceSynchronize(),都不会产生影响。在性能和效果方面,它应该完全相同。请注意,当使用事件来计算部分代码(例如,一个Cublas调用)时,调用cudaDeviceSynchronize()来获得有意义的测量值总是一种好习惯。根据我的经验,它不会带来任何重大开销,而且,使用它来计算内核的时间会更安全。

如果您的应用程序使用多个流,那么仅对您想要的流进行同步是有意义的。我相信this question会对您有所帮助。另外,您可以阅读CUDA C编程指南Section 3.2.5.5

答案 1 :(得分:2)

您的示例中不清楚您是否需要使用显式同步或为什么需要使用它。

发布到同一个流的CUDA操作被序列化。如果您启动内核或Cublas调用,然后使用cudaMemcpy操作(或cublasGetVector / Matrix等)跟踪该内核或cublas调用,则复制操作保证不会启动直到所有发布到同一个流的先前CUDA活动已完成。

一般情况的最佳做法是根本不使用显式同步。放置必须依赖于同一流的活动。在不同的流中放置彼此没有依赖关系的活动。

有很多cuda代码,使用cublas等,根本不使用显式同步。您的示例并不特别需要它。请注意,在您链接的第一个答案中,talonmies说:

  

您需要调用阻塞API例程,如同步内存传输或...

在你的例子中,这正是你要做的。您可以调用内存传输,发送到同一个流(例如cudaMemcpyAsync)或默认阻止传输(如cudaMemcpy),它会正常工作。无需显式同步。

您可能希望阅读appropriate programming guide section