2013-10-15 49 views
2

我有一个多线程CPU,我希望CPU的每个线程能够启动一个单独的CUDA流。单独的CPU线程将在不同的时间做不同的事情,所以有可能它们不会重叠,但如果它们同时启动CUDA内核,我希望它能够继续同时运行。在每个主机线程上创建一个cuda流(多线程CPU)

我很确定这是可能的,因为在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个流将被创建。这是做这件事的正确方法吗?如果两个或更多不同的主机线程在同一时间到达此代码,这是否会同时运行?谢谢你的帮助!

编辑:

我纠正一些语法问题中的代码块,并放在cudaMemcpyAsync作为sgar91建议。

+1

您不必'malloc''stream'指针。另外,如果你想让流重叠,你可以考虑使用'cudaMemcpyAsync'。 – sgarizvi

+0

@ sgar91:流将处于不同的上下文中,因此它们将永远不会重叠。 – talonmies

+0

@ sgar91谢谢!我已经在上面进行了这些修改。对于talonmies:那么没有办法让单独的CPU线程同时访问GPU设备吗?如何强制线程使用与Robert Crovella建议的相同的上下文? – Miggy

回答

2

它真的让我看起来像你提出了一个多进程应用程序,而不是多线程。你没有提到你想到的是哪种线程架构,甚至是操作系统,但是我所知道的线程体系结构并没有设置一个名为“main”的线程例程,并且你没有向线程代码展示任何序言。

多进程环境通常会为每个进程创建一个设备上下文,这会抑制细粒度的并发。即使这只是一个疏忽,我也会指出一个多线程应用程序应该在产生线程之前在所需的设备上建立一个GPU上下文。

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

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

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

内核是否碰巧并发运行或不是在上述问题已经解决后是一个单独的问题。并发内核执行的数量为requirements,并且内核本身必须具有兼容的资源需求(块,共享内存,寄存器等),这通常意味着“小”内核。

+0

谢谢你的回答。我很确定它是多线程的,因为构建应用程序的程序员说它是。我不知道,因为我没有建立它。不过,它是一种图像处理算法,我知道在我们的8核CPU(超线程至16个线程)上,它一次处理15个图像(一个线程仍然用于管理作业)。我使用窗户。名字main就是我所说的访问内核的.cu文件中的函数。它可以被称为任何东西。我会尝试你的建议和例子,然后回来。再次感谢。对不起,我的困惑。 – Miggy

+0

对不起,我花了这么长时间接受。我不得不搁置这个项目。我做了你所说的使用cudaOpenMP示例代码作为例子。我创建了一个C#程序,它使用System.Threading创建不同的CPU线程,每个线程都通过我的Cuda dll启动一个内核。我使用NVIDIA Visual Profilier进行测试,并可以验证它们是否在同一个Cuda上下文中以不同的流方式运行。我需要使用的主程序不是通过System.Threading创建线程,而是使用其他方法,所以我不确定如果这解决了我的问题,但是您将我设置在正确的轨道上。谢谢! – Miggy

相关问题