opencl内核线程中的竞争条件
如果多个线程同时写入单个内存位置,则会出现争用情况,对吗?? 就我而言,同样的情况也在发生 考虑“reduce.cl”中的一个模块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
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)