GPU线程分歧的高级问题

Advanced issues with GPU thread divergence

本文关键字:高级 问题 线程 GPU      更新时间:2023-10-16

我的情况-作为博士研究的一部分,我有一个动态编程算法要在GPU上使用OpenCL实现。与我合作的GPU包括AMD HD 7970、7750、A10-5800K APU和nVidia GTX 680。我了解获得良好绩效所需的原则和大多数最佳实践。

我的程序包含4个嵌套循环,在我的数据并行公式中,我能够展开其中的2个外循环。现在,由于问题的性质,最内部的循环不能不引起分歧。输出是一个表,表示机器上的作业时间表(计算机科学)。

当线程分叉(波前中的工作项采用不同的路线)时,我得到了错误的值,看起来好像工作项重复了自己。例如,

t=0,1,2,3,463,64,65,66,67
M1 0,0,0、9、。。。9、0、0、9、。。。

以上工作组的大小为64。t=63之前的第一个值是正确的,但请注意它是如何在t=64时再次重复的!它们不应该是零。在这里,每个工作项都映射到一个时间t。

如果我修复了导致分歧的参数,那么表中会完全填充预期的(错误的)结果,没有间隙(零),所以我得到了从t=0到TMAX的值9,其中TMAX是64的倍数。

问题-线程发散是否有导致错误计算或未定义线程行为的趋势?

我在互联网、文档、书籍上找到了关于线程分歧和记忆一致性的任何东西。我用不同的方式实现了整个程序,包括多次调用内核以排除全局内存不一致的方法,但结果都是一样的。

任何意见都将不胜感激。谢谢

经过进一步调查,我很惭愧在这里承认这一点,但其中一个计算条件给出了错误的值,因此看起来工作项的行为很奇怪,但事实并非如此。问题已纠正。谢谢

我认为你的问题很简单:你假设前64个线程将在下64个线程之前运行并完成。这不是真的,它们都是并行运行的。

事实上,您必须假设所有GLOBAL工作组大小都将并行运行,甚至以不确定的顺序运行(从结束到开始)。用户对内核执行的唯一限制是,每个线程(本地工作组大小)都将同时运行。这有助于在内部共享中间结果或共享存储器访问。

在您的情况下,如果本地工作组使用全局内存作为起点,那么前64个线程的工作组和第二个工作组将产生相同的结果。

请修改你的代码/算法,使之真正并行。从内核代码中粘贴也会很有帮助。