2012-02-16 179 views
6

对CUDA内核使用不同的流可以使并发内核执行成为可能。因此,n内核上的n流理论上可以并发运行,如果它们适合硬件,对吧?CUDA并行内核执行,每个流有多个内核

现在我面临以下问题:没有n不同的内核,但n*m其中m内核需要按顺序执行。例如n=2m=3会导致下面的执行方案与流:

Stream 1: <<<Kernel 0.1>>> <<<Kernel 1.1>>> <<<Kernel 2.1>>> 
Stream 2: <<<Kernel 0.2>>> <<<Kernel 1.2>>> <<<Kernel 2.2>>> 

我天真的假设是,内核X.0和Y.1至少应该同时执行(从一个理论点)或不是连续的(从实际的角度来看)。但是我的测量结果告诉我,情况并非如此,似乎是执行了连续执行(即K0.0,K1.0,K2.0,K0.1,K1.1,K2.1)。内核本身非常小,所以并发执行不应该成为问题。

现在我的方法是完成一种调度,以确保内核以交错方式进入GPU上的调度器。但是当处理大量的流/内核时,这可能会造成更多的伤害而不是好处。

好吧,直接点:什么是适当的(或至少不同)的方法来解决这种情况?

编辑:测量通过使用CUDA事件完成。我测量了完全解决计算所需的时间,即GPU必须计算所有的n * m内核。假设是:在完全并发的内核执行上,执行时间大致(理想情况下)是按顺序执行所有内核所需的时间的1/n倍,因此必须有两个或多个内核可以同时执行的时间。我现在只用两种不同的流来确保这一点。

我可以测量使用所描述的流和调度内核交错的执行时间之间的明显差异, Ë:

Loop: i = 0 to m 
    EnqueueKernel(Kernel i.1, Stream 1) 
    EnqueueKernel(Kernel i.2, Stream 2) 

Loop: i = 1 to n 
    Loop: j = 0 to m 
     EnqueueKernel(Kernel j.i, Stream i) 

后者导致更长的运行时间。

编辑#2:更改流号码开头1(而不是0,请参阅下面的注释)。

编辑#3:硬件是NVIDIA的Tesla M2090(即费米,计算能力2.0)

+0

您可能需要使用某些流同步基元来执行您所需的执行顺序。但是,您是否可以扩展一些关于如何在您的问题中进行测量的问题,并且您是否还可以确认,在编写“数据流0”时,您不一定是指CUDA数据流0? – talonmies 2012-02-16 12:42:03

+0

我澄清了测量(至少我希望如此)。对于流,我意指'cudaStream_t'的实例,如[CUDA C编程指南](http://developer.download.nvidia.com/compute/DevZone/docs/html/C/doc/CUDA_C_Programming_Guide.pdf)中所述。第3.2.5节(异步并发执行)。 – 2012-02-16 12:57:13

+2

也许你误解了我的要求 - 我的意思是你的一个流CUDA流0,因为流0(默认流)是同步的。 – talonmies 2012-02-16 13:09:28

回答

5

在费米(又名计算能力2.0),硬件最好是交错的内核启动到多个数据流,而不是将所有内核启动到一个流,然后是下一个流等。这是因为如果有足够的资源,硬件可以立即将内核启动到不同的流,而如果后续启动到同一个流,则通常会引入延迟,从而降低并发性。这就是你的第一种方法表现更好的原因,这种方法是你应该选择的方法。

启用性能分析还可以禁用费米的并发性,所以要小心。另外,请注意在启动循环期间使用CUDA事件,因为这些干扰可能会干扰 - 例如,最好使用事件的整个循环来计时。

+0

你能否给我一个知识源(第一段而不是第二段)来自哪里? – 2012-02-21 13:37:43

+0

CUDA 4.1编程指南的第3部分有信息。然而,在阅读它之后,我发现它没有明确地说“交织内核启动”。我从NVIDIA CUDA软件团队的同事处获得了相关信息。 – harrism 2012-02-22 00:59:09

+0

感谢您的更新。如果可能,我将重新访问我的代码并提供更多信息/更新。 – 2012-02-22 07:55:16