cudaDeviceSynchronize 和 cudaStreamSynchronize

我的理解

CUDA 的 API 都是和 device 相关的,调用前要先确保已经调用过 cudaSetDevice 将 context 关联到相关的设备上(据 Stackoverflow 的老提问,这个 context 会占用 150 MB 显存;从我这边来看,这个显存占用量还更大一些,有 200300 MB)。创建流是不需要提供设备号的,所以它肯定使用的是 thread_local 的 device。

也就是说,每个流是和设备关联起来的,用 cudaDeviceSynchronize 实际上是同步了这个设备上所有的流,而 cudaStreamSynchronize 是同步了单个流。前者的同步范围更大

根据 Stackoverflow 的这个回答cudaStreamSynchronize 的默认参数是 nullptr,也就是默认流,同步它相当于同步当前设备上的所有阻塞流。由于可以创建非阻塞流,所以就算不给 cudaStreamSynchronize 传参或者传 nullptr,效果也和 cudaDeviceSynchronize() 可能是不一样的。

cudaStreamCreateWithFlags( stream_0, cudaStreamNonBlocking );
cudaStreamCreate( stream_1 );
// ...
cudaStreamSynchronize( nullptr ); // sync with stream_1 and legacy stream
cudaDeviceSynchronize(); // sync with stream_0, stream_1 and legacy

其他

cudaThreadSynchronize 方法和 cudaDeviceSynchronize 很相似,前者是过时方法,建议使用后者。