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
很相似,前者是过时方法,建议使用后者。