我最近一直在使用 openCL。我创建了一个基本上采用一个全局变量的内核 由内核中的所有工作项共享。内核再简单不过了,每个工作项都会增加 result 的值,这是全局变量。代码已显示。
__kernel void accumulate(__global int* result) {
*result = 0;
atomic_add(result, 1);
}
当工作项总数很小时,一切都会顺利进行。在我的 MAC pro retina 上,当工作项约为 400 时,结果是正确的。
但是,当我增加全局大小时,例如 10000。而不是在获取时获取 10000 返回结果中存储的数字,该值约为 900,这意味着多个工作项可能会同时访问全局。
我想知道此类问题的可能解决方案是什么?感谢您的帮助!
最佳答案
*result = 0;
看起来像问题所在。对于较小的全局大小,每个工作项都会执行此操作,然后自动递增,从而为您提供正确的计数。但是,当全局大小变得大于可以同时运行的数量(这意味着它们分批运行)时,后续批处理会将结果重置回 0。这就是为什么您没有获得完整计数的原因。解决方案:从主机端初始化缓冲区,应该没问题。或者,要在设备上进行初始化,您可以仅从 global_id == 0 初始化它,执行屏障,然后执行原子增量。
关于当总工作项很大时,opencl 原子操作不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22290565/