2012-08-24 53 views
0

我有一个包含两个主要任务的算法。这两项任务都是令人尴尬的平行。所以我可以通过以下方式之一在CUDA上移植此算法。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中的论文表示,第二种方法在适当的护理下可以表现得更好。但总的来说应该遵循哪种方法?

+3

尝试一下,看看。 – GManNickG

+0

我得到的结果赞成第一种方法,有时赞成第二种方法。文献中推荐什么? –

+0

在这种情况下,确保第二种方法跟在纸上,看是否需要边缘。如果两者仍然相对相同(并且这是与您将要使用的真实数据),请保留您想要的数据。只是尽量保持切换它们的能力,所以你可以随时测试。 – GManNickG

回答

2

目前还没有任何官方支持的方法在CUDA编程模型中通过单个内核执行跨线程块进行同步。根据我的经验,这样做的方法会导致代码变得脆弱,导致在不断变化的环境下发生不正确的行为,例如在不同硬件上运行,更改驱动程序和CUDA发行版等。

仅仅因为学术刊物发布并不意味着它是生产代码的安全想法。

我建议你坚持你的方法1,我问你这个问题:你确定把你的计算分成两个单独的内核真的会导致性能问题吗?第二个内核的开销肯定是瓶颈?

+0

“您是否确定将计算分离为两个单独的内核实际上会导致性能问题?” - 不完全是,但回到CPU的想法在我的应用程序中并不好,我想为任务集启动N个线程,并忘记从CPU端(这样CPU线程可以做一些其他有用的工作)。所以我是想知道是否可以在设备上的所有线程上同步,但是如果同步的代价很高,那么我必须使用“智能”的东西,以便在执行期间不要求我的应用程序来到CPU。 harrism: –

+0

:我已经阅读了关于前缀总和的GPU宝石3中的章节,但我还没有看到源代码。在那个实现中你使用了上面哪个方法? –

+0

对于您的第一条评论,您可能会对即将推出的Kepler GK110 GPU中的CUDA Dynamic Parallelism感兴趣 - 它使内核可以启动其他内核(以及其他内核)。对于你的第二个评论:我总是使用方法1:在我看来,阻止同步的唯一安全方法是启动另一个内核。 – harrism

相关问题