我的情况 - 我有一个动态编程算法,可以在我的博士研究中使用OpenCL在GPU上实现。我正在使用的GPU包括AMD HD 7970,7750,A10-5800K APU和nVidia GTX 680.我理解所涉及的原则以及获得良好性能所需的大多数最佳实践。
我的程序包含4个嵌套循环,在我的数据并行公式中,我能够展开2个外循环。现在由于问题的本质,最内层的循环不能没有引起分歧。输出是一个表格,表示机器上的作业计划(计算机科学)。
当线程发散(wavefront中的工作项采用不同的路径)时,我得到错误的值,看起来工作项重复自己。例如,
t = 0,1,2,3,4,... 63 ,64,65,66,67,... M1 0,0,0,9,9,... 9,0,0,0,9,......
在工作组大小之上是64.第一个值t = 63是正确的,但注意它在t = 64时再次重复!它们不应该是零。这里每个工作项都映射到时间t。
如果我修复导致分歧的参数,表格会完全填满预期的(错误的)结果,没有间隙(零),所以我从t = 0到TMAX获得值9,其中TMAX是64。
问题 - 线程分歧是否会导致错误的计算或未定义的线程行为?
我已经挖掘了互联网,文档,书籍,我可以找到有关线程分歧和内存一致性的任何内容。我已经以不同的方式实现了整个程序,包括多次调用内核以排除全局内存不一致但结果都是一样的。
任何输入都将不胜感激。谢谢!
答案 0 :(得分:1)
经过进一步调查后,我很惭愧在这里承认这一点,但其中一个计算条件是给出了错误的值,所以看起来工作项目表现得很奇怪,但事实并非如此。问题得到纠正谢谢!
答案 1 :(得分:0)
我认为你的问题很简单:你正在考虑前64个线程将运行并在接下来的64个线程之前完成。事实并非如此,所有这些都并行运行。
实际上,您必须假设所有GLOBAL工作组大小将并行运行或甚至以非确定性顺序运行(从结束到开始)。 用户可以进行内核执行的唯一约束是每个线程组(本地工作组大小)将同时运行。这有助于在内部共享中间结果或共享内存访问。
在您的情况下,如果本地工作组使用全局内存作为起点,那么前64个线程工作组和第二个将产生相同的结果。
请修改您的代码/算法,使其真正并行。来自内核代码的粘贴也会有所帮助。