【问题标题】:error CL_OUT_OF_RESOURCES while reading back data in host memory while using atomic function in opencl kernel在opencl内核中使用原子函数时读回主机内存中的数据时出现错误CL_OUT_OF_RESOURCES
【发布时间】:2013-02-05 05:59:01
【问题描述】:

我正在尝试在我的 opencl 内核中实现原子函数。我正在创建的多个线程并行尝试写入单个内存位置。我希望他们在特定的代码行上执行串行执行。我以前从未使用过原子函数。

我在许多博客和论坛上发现了类似的问题,我正在尝试一种解决方案。即使用两个不同的函数“获取”和“释放”来锁定和解锁信号量。我已经包含了必要的 opencl 扩展,我的设备 (NVIDIA GeForce GTX 630M) 肯定都支持这些扩展。

我的内核执行配置:

global_item_size = 8;
ret = clEnqueueNDRangeKernel(command_queue2, kernel2, 1, NULL, &global_item_size2, &local_item_size2, 0, NULL, NULL);

这是我的代码:reducer.cl

#pragma OPENCL EXTENSION cl_khr_fp64 : enable
#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable
#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable
#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable
#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable

typedef struct data
{
  double dattr[10];
  int d_id;
  int bestCent;
}Data;

typedef struct cent
{
  double cattr[5];
  int c_id;
}Cent;

__global void acquire(__global int* mutex)
{
    int occupied;
    do {
        occupied = atom_xchg(mutex, 1);
    } while (occupied>0);
}

__global void release(__global int* mutex)
{
    atom_xchg(mutex, 0); //the previous value, which is returned, is ignored
}

__kernel void reducer(__global int *keyMobj, __global int *valueMobj,__global Data *dataMobj,__global Cent *centMobj,__global int *countMobj,__global double *sumMobj, __global int *mutex)
{
  __local double sum[2][2];
  __local int cnt[2];

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

  if(i<2)
    cnt[i] = countMobj[i];
  barrier(CLK_GLOBAL_MEM_FENCE);

  n = keyMobj[i];
  for(j=0; j<2; j++)
  {
     barrier(CLK_GLOBAL_MEM_FENCE);
          acquire(mutex);
             sum[n][j] += dataMobj[i].dattr[j];
      release(mutex);
  }

  if(i<2)
  {
    for(j=0; j<2; j++)
    {
       sum[i][j] = sum[i][j]/countMobj[i];
       centMobj[i].cattr[j] = sum[i][j];
    }
  }
}

不幸的是,该解决方案似乎对我不起作用。当我将 centMobj 读回主机内存时,使用

ret = clEnqueueReadBuffer(command_queue2, centMobj, CL_TRUE, 0, (sizeof(Cent) * 2),  centNode, 0, NULL, NULL);
ret = clEnqueueReadBuffer(command_queue2, sumMobj, CL_TRUE, 0, (sizeof(double) * 2 * 2), sum, 0, NULL, NULL);

它给我错误代码 = -5 (CL_OUT_OF_RESOURCES) 对于 centMobj 和 sumMobj。

如果我的原子函数代码有任何问题,或者问题在于将数据读回主机内存,我不知道。如果我错误地使用了原子函数,请纠正我。 提前谢谢你。

【问题讨论】:

    标签: opencl gpgpu gpu


    【解决方案1】:

    在 OpenCL 中,工作项之间的同步只能在工作组内完成。尝试在不同工作组之间同步工作项的代码可能在一些非常具体的(和实现/设备相关的)情况下工作,但在一般情况下会失败

    解决方案是使用原子来序列化对同一内存位置的访问(但不会阻塞任何工作项),或者以不同的方式重新设计代码。

    【讨论】:

    • 你的意思是我不能在属于不同组的工作项之间进行同步?即使有原子功能?如果我保持 local_work_size = 1 怎么办?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-24
    • 2020-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多