opencl内核线程中的竞争条件

opencl内核线程中的竞争条件,opencl,gpgpu,gpu,Opencl,Gpgpu,Gpu,如果多个线程同时写入单个内存位置,则会出现争用情况,对吗?? 就我而言,同样的情况也在发生 考虑“reduce.cl”中的一个模块 int i = get_global_id(0); int n,j; n = keyMobj[i]; // this n is the key..It can be either 0 or 1. for(j=0; j<2; j++) sumMobj[n*2+j] += dataMobj[i].dattr

如果多个线程同时写入单个内存位置,则会出现争用情况,对吗?? 就我而言,同样的情况也在发生

考虑“reduce.cl”中的一个模块

int i = get_global_id(0);
int n,j;

n = keyMobj[i];                       // this n is the key..It can be either 0 or 1.
for(j=0; j<2; j++)
      sumMobj[n*2+j] += dataMobj[i].dattr[j];        //summing operation.
inti=get\u global\u id(0);
int n,j;
n=keyMobj[i];//这个n是键..它可以是0或1。
对于(j=0;j[…0…,…1…],同时访问4个线程&
summabj===>[..3…,..4…]同时被6个线程访问


还有什么方法可以使它并行,比如使用锁定或信号量?因为这个求和在我的算法中是一个非常重要的部分…

我可以给你一些提示,因为我也面临类似的问题

我可以想出三种不同的方法来实现类似的目标:

考虑一个简单的内核,假设您启动了4(0-3)个线程

您希望将值p[0]、p[1]、p[2]、p[3]、p[4]相加,并将最终和存储在p[4]中。对吗?即:

p[4]= p[0] + p[1] + p[2] + p[3] + p[4] 
方法-1(无并行性)

仅将此作业分配给1个线程(无并行性):

方法2(具有并行性)

将您的问题表述如下:

p[4]= p[0] + p[1] + p[2] + p[3] + p[4] + 0  
这是一个减排问题

因此,在第一次迭代中启动3个线程:i=0到i=2

 i=0 finds p[0] + p[1]
 i=1 finds p[2] + p[3]  
 i=2 finds p[4] + 0
现在有了三个数字,应用与上面相同的逻辑并添加这些数字(适当的填充为0,使其为二的幂)

方法-3原子操作

如果您仍然需要以原子方式实现此功能,可以使用:

描述

读取存储在指定位置的32位值(称为旧值) 通过p.计算(old+val)并将结果存储在p.指定的位置。 该函数返回old


这是假设数据是int类型的。否则您可以看到上面建议的。这些是sumMobj和dataMobj typedef struct data{double dattr[10];int d_id;int bestCent;}data;data*dataMboj;和double*sumMobj=(double*)malloc(sizeof(double)*2*2)的定义@Talonmes这实际上是并行加法问题..在opencl内核中。我只是不知道可行的解决方案。如果你怀疑存在竞争条件,为什么不使用barrier?比如barrier(CLK_LOCAL_MEM_FENCE);@ocluser我有多个线程同时访问(写入)单个内存位置。此功能是否为“屏障”(CLK_LOCAL_MEM_FENCE)'在这种情况下有用吗?我以前没有使用过它。这解释了一种原子添加浮点数的方法,但是您需要使用cl_khr_int64_base_原子,并使用long和double的并集。这意味着如果我使用浮点运算,那么除了使用reduction方法之外,我没有其他选择,正如我在这里所做的那样没有为基于浮点的原子操作提供任何扩展(就我的信息而言)。我说的对吗?除了缩减,你还可以看到@Slicedpan发布的
p[4]= p[0] + p[1] + p[2] + p[3] + p[4] + 0  
 i=0 finds p[0] + p[1]
 i=1 finds p[2] + p[3]  
 i=2 finds p[4] + 0
  int fsfunc atomic_add (   volatile __global int *p ,int val)