CUDA同步内核

6

您好,我对CUDA编程有一个疑问。 我有以下代码:

int main () {

    for (;;) {
        kernel_1 (x1, x2, ....);
        kernel_2 (x1, x2 ...);
        kernel_3_Reduction (x1);

    // code manipulation host_x1
    // Copy the pointer device to host
        cpy (host_x1, x1, DeviceToHost)
        cpu_code_x1_manipulation;
        kernel_ (x1, x2, ....);
    }

}

那么,何时制作副本并如何确保kernel_1、kernel_2和kernel_3完成了它们的任务?


除非您使用流和其他结构,否则所有的CUDA调用(内核、cudamemCpy等)都将在默认流中发出,并且它们将是阻塞的(直到前面的CUDA调用完成才会开始)。只要您不切换流,cudaMemcpy将不会在完成之前将控制返回给CPU线程。同样地,cudaMemcpy也不会在所有先前的CUDA调用完成之前开始。 - Robert Crovella
2个回答

11

在同一个流上启动的所有操作都是同步的。在上面的代码中,所有内核将一个接一个地运行。如果您需要kernel_1和kernel_2并行运行,则必须显式指定流。

所有在同一流上启动的操作都会被同步执行。在以上的代码中,所有的kernel都将一个接一个地运行。如果您需要kernel_1和kernel_2并行运行,则需要显式指定流。

3
需要注意的是,并非所有的CUDA设备都支持并发执行内核。当然,如果存在多个CUDA设备,则它们可以并行运行内核。 - datenwolf
1
我相信,在Fermi及更高架构的CC 2.x及更高版本上,实际上可以在单个GPU设备上启动多达16个并发内核。http://developer.download.nvidia.com/CUDA/training/StreamsAndConcurrencyWebinar.pdf - Recker
我想按顺序实现kernel_1、kernel_2和kernel_3,即CPU会一直停止,直到执行完所有的kernel。 - user1704397
@user1704397,上面的代码将完成这个任务,但是CPU不会等待工作完成。在第三个内核调用之后使用cudaDeviceSynchronize()来等待工作完成,就像ahmad在另一个答案中建议的那样。 - Eugene

5

只需在需要确保所有内核完成的位置使用cudaDeviceSynchronize();。在此命令之后,您可以假定所有内核和所有待处理设备函数调用都已完成。


谢谢回复! 当执行 kernel_3_reduction(x1) 时,结果并不如预期。 显然,在 kernel_1 和 kernel_2 中进行的计算尚未完成。为确保 kernel_1 和 kernel_2 已经完成,我使用了以下代码: kernel_1(); cudaDeviceSynchronize(); kernel_2(); cudaDeviceSynchronize(); kernel_3_reduction(); cudaDeviceSynchronize(); cpy(host_x1, x1, DeviceToHost); cpu_code_x1_manipulation; kernel_4(x1, x2, ....); cudaDeviceSynchronize(); - user1704397
我想按顺序实现kernel_1、kernel_2和kernel_3,即CPU会一直停止,直到执行完所有的kernel。 - user1704397

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接