Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Concurrency CUDA并发内核执行,每个流有多个内核_Concurrency_Cuda - Fatal编程技术网

Concurrency CUDA并发内核执行,每个流有多个内核

Concurrency CUDA并发内核执行,每个流有多个内核,concurrency,cuda,Concurrency,Cuda,对CUDA内核使用不同的流使并发内核执行成为可能。因此n流上的n内核理论上可以并发运行,如果它们适合硬件,对吗 现在我面临以下问题:没有n不同的内核,而是n*m其中m内核需要按顺序执行。例如,n=2和m=3将导致以下具有流的执行方案: Stream 1: <<<Kernel 0.1>>> <<<Kernel 1.1>>> <<<Kernel 2.1>>> Stream 2: <<

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

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

Stream 1: <<<Kernel 0.1>>> <<<Kernel 1.1>>> <<<Kernel 2.1>>>
Stream 2: <<<Kernel 0.2>>> <<<Kernel 1.2>>> <<<Kernel 2.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)

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


启用评测也可以禁用费米上的并发,所以要小心。另外,在启动循环期间使用CUDA事件时要小心,因为它们可能会产生干扰——例如,最好在执行过程中使用事件对整个循环计时。

您可能需要使用一些流同步原语来强制执行所需的执行顺序。但是,你能不能在你的问题中进一步阐述一下你是如何进行测量的?你能不能确认,当你写“流0”时,你的意思不是CUDA流0?我澄清了测量结果(至少我希望如此)。对于streams,我指的是第3.2.5节(异步并发执行)中所述的
cudaStream\u t
的实例。也许您误解了我的要求——我的意思是,是您的一个流CUDA stream 0,因为stream 0(默认流)是同步的。我必须对此进行检查,很抱歉,没有立即提供更令人满意的答案。我想请你为我提供一个关于该声明来源的参考(可能我在文档中对此进行了监督)。我不得不问,你是否使用费米+gpu?你能告诉我这些知识(在第一段,而不是第二段)的来源吗?CUDA 4.1编程指南的第3节中有相关信息。然而,在阅读之后,我发现它并没有明确地说“交错内核启动”。我从英伟达CUDA软件团队的同事那里得到了信息,谢谢更新。我将重新访问我的代码,并提供更多信息/更新,如果可能的话。好的,根据这些信息,我引入了交错,这解决了问题。不过,如果CUDA编程指南能够解决这个问题,那就太好了。调度的技术细节见幻灯片15,随后是一系列示例幻灯片。
Loop: i = 1 to n
    Loop: j = 0 to m
        EnqueueKernel(Kernel j.i, Stream i)