【发布时间】:2012-08-27 08:09:09
【问题描述】:
我有一个包含两个主要任务的算法。这两个任务令人尴尬地并行。所以我可以通过以下方式之一将这个算法移植到CUDA上。
>Kernel<<<
Block,Threads>>>() \\\For task1
cudaThreadSynchronize();
>Kerne2<<<
Block,Threads>>>() \\\For task2
或者我可以做以下事情。
>Kernel<<<
Block,Threads>>>()
{
1.Threads work on task 1.
2.syncronizes across device.
3.Start for task 2.
}
可以注意到,在第一种方法中,我们必须回到 CPU,而在第二种趋势中,我们必须在 CUDA 中的所有块之间使用同步。 IPDPS 10 中的论文说,第二种方法,在适当的照顾下可以表现得更好。但是一般应该遵循哪种方法呢?
【问题讨论】:
-
我得到的结果支持第一种方法,有时支持第二种方法。文献推荐什么?
-
在这种情况下,请确保第二种方法很好地跟随纸张,看它是否占据边缘。如果两者仍然相对相同(这是您将使用的真实数据),请保留您想要的任何一个。尽量让您可以随时切换它们,这样您就可以随时进行测试。
-
你为什么不想使用流呢? Fermi 支持并发内核执行,因此您可以同时启动两个内核(当然,如果它们不相互依赖)。否则,在我看来,块间同步是一件非常讨厌的事情:在您提到的那篇论文中,它仅在线程块到多处理器的一对一映射时才有效。我不会诚实地使用它..
-
坦率地说,纸上谈兵的想法在现实中是行不通的。在某些情况下,它会花费太多时间,因此驱动程序正在终止内核执行。我想到了流,但在我的情况下,task2 依赖于 task1,所以只有 2 个解决方案..要么回到 CPU,要么设法实现跨块同步(无论如何)。块数较少的情况下块间同步很好,但如果我们有大量块,则不可靠,这很明显,因为块间同步机制中的while循环会消磨时间。
-
作为一种经典的优化模式,您还可以考虑将数据拆分为在内核调用期间不相互依赖的块。然后可以在单独的流中处理每个块,从而在内核执行中提供一些部分重叠
标签: performance cuda