cudaMemcpy()调用流

时间:2012-08-16 13:00:38

标签: cuda

考虑两段代码。

Snippet1

cudaStream_t stream1, stream2 ;
cudaStreamCreate(&stream1);
cudaStreamCreate(&stream2);
cudaMemcpyAsync( dst, src, size, dir, stream1 );
kernel<<<grid, block, 0, stream2>>>(...);



Snippet2
cudaStreamCreate(&stream1);
cudaStreamCreate(&stream2);
cudaMemcpy( dst, src, size, dir, stream1 );
kernel<<<grid, block, 0, stream2>>>(...);

在两个片段中,我发出了一个memcpy调用(snippet1异步和snippet2同步)

由于命令已发布到两个不同的流,根据我的理解,两种情况都可能存在重叠。

但是在Snippet2中,cudaMemcpy调用同步(又称阻塞)导致了一个矛盾的结论,即cudaMemcpy和内核调用将一个接一个地执行。

哪一个是正确的结论?

更紧凑地改写:当我们向流发出cudaMemcpy调用时,是否会阻止“整个代码”或阻止它发出的流?

1 个答案:

答案 0 :(得分:0)

ArcheaSoftware部分正确。实际上,在操作完成之前,同步调用不会将控制权返回给CPU。从这种意义上说,只有在cudaMemcpy调用返回之后,才会启动内核。但是,取决于您的缓冲区类型,内核可能会或可能无法使用通过cudaMemcpy调用传输的数据。下面是一些示例:

示例1:

cudaMallocHost(&src, size);
cudaMalloc(&dst, size);
cudaMemcpy(dst, src, size, cudaMemcpyHostToDevice);
kernel<<<grid, block, 0, stream2>>>(...);

在这种情况下,内核可以使用从src复制到dst的数据。

示例2:

src = malloc(size);
cudaMalloc(&dst, size);
cudaMemcpy(dst, src, size, cudaMemcpyHostToDevice);
kernel<<<grid, block, 0, stream2>>>(...);

在这种情况下,cudaMemcpy可以在实际将数据传输到设备之前返回。

来自未注册主机缓冲区(例如cudaMemcpy缓冲区)的

malloc仅保证在将数据复制到源缓冲区的 out 中,也许复制到中间暂存缓冲区之前,通话返回。这是令人惊讶的行为,但在NVIDIA CUDA文档中已对此进行了定义。参考:https://docs.nvidia.com/cuda/cuda-runtime-api/api-sync-behavior.html#api-sync-behavior

通常,由于这种行为,我建议避免使用未注册的主机缓冲区。

相关问题