【问题标题】:Opencl atomic_add() function returns wrong valueOpencl atomic_add() 函数返回错误值
【发布时间】:2017-03-30 15:32:35
【问题描述】:

我在 OpenCL 1.2 中遇到问题。 看,我在内核中有一个数组为__global,组大小为1000。 问题是atomic_add()函数不能正常工作。

我的内核代码是:

__kernel void kernelfunction(__global uint32_t* buffer){

buffer[3] = 100;

atomic_add(&buffer[3], 1);

...

}

如果我创建 1000 个线程,我预计 buffer[3] 的值将是 1100,对吗? 但是程序的行为是未定义的。 有时是 1100,有时是 1064,有时是 1093,然后......

我尝试过的:

我还启用了如下的 opencl 扩展:

#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable

但问题仍然存在。 在另一个项目中,我将创建一个简单的 opencl 项目,atomic_add 工作正常,我检查了几乎整个项目配置,但我不知道问题出在哪里。

你能帮帮我吗? 谢谢

【问题讨论】:

  • 不,你错了。您还应该研究如何正确格式化您的代码。我也不知道为什么你的第一行是“玩得开心”。

标签: c++ c opencl


【解决方案1】:

如果没有原子,对同一元素进行简单访问时会出现竞争条件,更糟糕的是,所有数据都可能已按计算单元缓存,并且在内核结束之前不会更新。

buffer[3] = 100;

这是未定义的行为。结果甚至可能是 101;

如果没有同步命令,即使是同一个本地组中的线程也不能有真正的数据。

初始化应该由主机进行,因为 gpu 并发运行线程。不是连续的,不包括原子。或者,您为其自己的组进行初始化(从其他组中不可见)并在之后添加一个barrier(CLK_GLOBAL_MEM_FENCE),以便同一组中的其他线程可以正确看到它。

【讨论】:

  • 是的,你是对的,谢谢,但有时我需要更改(初始化)OpenCL 内核中缓冲区的元素 3 并防止银行冲突,我的行为是这样的:如果( id == 0)缓冲区[3] = 100;但尽管问题仍然存在。亲爱的侯赛因,我现在该怎么办?
  • 在if语句之后,添加一个barrier。但这仅适用于该工作组。对于全局线程,需要在 cpu 宿主程序中初始化
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-28
  • 2011-03-15
  • 2020-11-22
  • 2019-05-02
  • 2019-11-07
  • 2019-04-13
  • 1970-01-01
相关资源
最近更新 更多