【问题标题】:CUDA inter-kernel communication between different streams不同流之间的CUDA内核间通信
【发布时间】:2026-01-31 20:15:01
【问题描述】:

有没有人在 2 个不同的 CUDA 流中成功运行 2 个不同的内核并让它们同步?基本上我想让 1 个内核 A 将数据发送到另一个同时运行的内核 B(在不同的流中),然后返回结果。原因:内核 A 在 1 个 CUDA 线程中运行,我想要内核 B 的多 GPU 线程实现。

这是使用高端 GPU (Fermi/Tesla)、CUDA 4.2

相同的 GPU,不同的流。所以数据应该可以通过设备内存进行通信,但是如何同步它们呢?

【问题讨论】:

  • 您在没有说明问题的情况下询问特定解决方案是否可行。在这个特定的例子中,您会发现更好地陈述您的问题,以便社区可以为您提供受 CUDA 编程模型支持的解决方案。

标签: cuda sync


【解决方案1】:

CUDA 编程模型仅支持同一线程块中的线程之间的通信(CUDA C Programming Guide 在第 2.2 节线程层次结构的末尾)。这不能通过当前的 CUDA API 可靠地实现。如果您尝试,您可能会发现部分成功。但是,这会在不同的操作系统、应用程序的不同执行上失败,并且这将被未来的驱动程序更新和新硬件打破(GK110 支持增强的并发模型)。

【讨论】:

    【解决方案2】:

    如果我没看错你的问题,你有两个问题:

    1. 内核间数据交换
    2. 内核间同步

    1) 内核间数据交换可以通过共享设备全局内存中的数据来实现。

    2) 据我所知,CUDA 没有提供可靠的内核间同步工具。而且我不知道可以在这里应用任何合适的技巧。

    CUDA C Programming Gide v7.5 告诉我们: “应用程序通过流管理上述并发操作。流是按顺序执行的命令序列(可能由不同的主机线程发出)。另一方面,不同的流可能相对于一个流无序地执行它们的命令另一个或同时发生;此行为无法保证,因此不应依赖其正确性(例如,内核间通信未定义)。”

    【讨论】:

      【解决方案3】:

      您需要在主机上进行同步。从我的脑海中,依次为每个流调用 cudaDeviceSynchronize 应该可以解决问题,但它可能并不那么容易。

      【讨论】:

        【解决方案4】:
        • 您的数据必须在全局内存中
        • 需要获取主机上的数据地址
        • 您必须将此数据发送回第二个内核

        您的代码必须与此类似:

        *dataToExchange_h,*dataToExchange_d;
        cudaMalloc((void**)dataToExchange, sizeof(data));

        内核1>>(dataToExchange);
        cudaStreamSynchronize(stream1);
        kernel2>>(dataToExchange);

        但请注意,流同步会减慢该过程,因此您应尽可能避免它。 您还可以通过 cuda 事件获得流同步,它不太明显并且没有特别的优势,但了解它很有用;-)

        【讨论】:

          最近更新 更多