在每个主机线程(多线程 CPU)上创建一个 cuda 流



我有一个多线程CPU,我希望CPU的每个线程都能够启动单独的CUDA流。 单独的 CPU 线程将在不同的时间做不同的事情,因此它们可能不会重叠,但如果它们同时启动 CUDA 内核,我希望它继续并发运行。

我很确定这是可能的,因为在 CUDA 工具包文档第 3.2.5.5 节中。它说"流是一系列命令(可能由不同的主机线程发出)..."

所以如果我想实现这一点,我会做类似的事情

void main(int CPU_ThreadID) {
    cudaStream_t *stream;
    cudaStreamCreate(&stream);
    int *d_a;
    int *a;
    cudaMalloc((void**)&d_a, 100*sizeof(int));
    cudaMallocHost((void**)&a, 100*8*sizeof(int));
    cudaMemcpyAsync(d_a, a[100*CPU_ThreadID], 100*size(int), cudaMemcpyHostToDevice, stream);
    sum<<<100,32,0,stream>>>(d_a);
    cudaStreamDestroy(stream);
}

这只是一个简单的例子。 如果我知道只有 8 个 CPU 线程,那么我知道最多会创建 8 个流。 这是正确的方法吗? 如果两个或多个不同的主机线程大约同时到达此代码,这会同时运行吗? 感谢您的任何帮助!

编辑:

我纠正了代码块中的一些语法问题,并按照 sgar91 的建议放入了 cudaMemcpyAsync。

在我看来,

您确实在提出一个多进程应用程序,而不是多线程应用程序。 你没有提到你想到的是哪个线程架构,甚至没有提到操作系统,但我所知道的线程架构没有假设一个名为"main"的线程例程,你也没有展示线程代码的任何前导码。

多进程环境通常会为每个进程创建一个设备上下文,这将抑制细粒度并发。

即使这只是一个疏忽,我也会指出,在生成线程之前,多线程应用程序应该在所需的设备上建立 GPU 上下文。

然后,每个线程可以发出cudaSetDevice(0);或类似的调用,这应该会导致每个线程在指示的设备上选取已建立的上下文。

一旦就位,您应该能够从您喜欢的任何线程向所需的流发出命令。

您可能希望参考 cudaOpenMP 示例代码。 虽然它省略了流概念,但它演示了一个多线程应用程序,该应用具有多个线程向同一设备发出命令的潜力(并且可以扩展到同一流)

在解决上述问题后,内核是否碰巧同时运行是一个单独的问题。 并发内核执行有许多要求,内核本身必须具有兼容的资源需求(块、共享内存、寄存器等),这通常意味着"小"内核。

最新更新