0

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

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

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

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 的倍数。

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

我已经在互联网、文档和书籍中挖掘了有关线程分歧和内存一致性的任何内容。我以不同的方式实现了整个程序,包括多次调用内核以排除全局内存不一致,但结果都是一样的。

任何输入将不胜感激。谢谢!

4

2 回答 2

1

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

于 2013-07-25T18:05:10.357 回答
0

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

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

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

请修改您的代码/算法以使其真正并行。从您的内核代码粘贴也将有所帮助。

于 2013-07-25T12:23:43.237 回答