同步嵌套内核的深度

时间:2018-05-22 19:10:55

标签: c++ cuda dynamic-parallelism

让我们在有父内核和子内核的地方使用以下代码。从所述父内核开始,我们希望在不同的流中启动threadIdx.x子内核以最大化并行吞吐量。然后我们等待那些cudaDeviceSynchronize()的子节点作为父内核需要查看对global内存所做的更改。

现在假设我们还希望用流启动n父内核,并且在我们希望并行启动的每组n父内核之间,我们还必须使用{{1}等待结果}}

这会如何表现?

this official introduction to Dynamic Parallelism by Nvidia我会认为cudaDeviceSynchronize()只会等待在其中启动的流。它是否正确?如果没有,会发生什么?

注意:我知道只有这么多流可以一次运行(在我的情况下是32)但这更多是为了最大化占用

编辑:一些代码示例

parent kernel[0]

1 个答案:

答案 0 :(得分:3)

在父内核完成之前,父内核将等待任何生成的子内核完成。这包含在dynamic parallelism documentation

  

子网格的调用和完成是正确嵌套的,这意味着在其线程创建的所有子网格都已完成之前,父网格不会被视为完成。即使调用的线程没有在启动的子网格上显式同步,运行时也保证父和子之间的隐式同步。

任何其他语义都应该可以从普通的流语义中推断出来,即:在发送到该流中的所有先前活动完成之前,启动到特定流中的活动才会开始。同样,在单独的流中启动的活动之间没有强制排序。

在您的示例中(或者实际上在任何示例中),父内核将等待,直到从该父内核启动的所有子内核都已完成,无论使用或未使用哪些流。

目前尚不清楚您是否在询问此问题,但请注意,对于示例中的设备代码,cudaDeviceSynchronize()仅保证该线程将等待子内核完成,同样只强制执行结果可见性,为该线程订购。如果您希望同一块中的其他线程能够看到线程0生成的子内核的全局内存结果(只是为了选择一个示例),那么您可能希望在线程0中跟进cudaDeviceSynchronize()操作__syncthreads()操作。在那个__syncthreads()之后,同一个块中的其他线程将保证可以看到由线程0(或由任何线程启动的子内核,然后是cudaDeviceSynchronize()调用)启动的子内核产生的全局结果,在前面提到的__syncthreads())之前。

CDP环境中要注意的其他几个限制是nesting limitpending launch limit