0

我使用本地内存在 opencl 中编写了一个内核以获得更快的执行速度。这是我第一次使用本地内存。我的 global_work_size = 16 和 local_work_size = 8。

Opencl 内核:mapper.cl

#pragma OPENCL EXTENSION cl_khr_fp64 : enable
typedef struct data
{
  double dattr[10];
  int d_id;
  int bestCent;
}Data;


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

__kernel void mapper(__global int *keyMobj, __global int *valueMobj, __global Data *dataMobj, __global Cent *centMobj)
{
    int bx   = get_group_id(0);    
    int tx   = get_local_id(0);
    int size = get_local_size(0);

    __local double localData[8][2];
    __local double localCent[2][2];
    __local int local_id[8];

    int index = tx + bx*size;

    int j,k,color=0;
    double dmin=1000000.0, dx;

    for(j=0; j<2; j++)
    {
          if(tx<2)
              localCent[tx][j] = centMobj[tx].cattr[j];

          localData[tx][j] = dataMobj[index].dattr[j];
          local_id[tx] = dataMobj[index].d_id;

    }
barrier(CLK_LOCAL_MEM_FENCE); 


    for(j=0; j<2; j++)     
     {
        dx = 0.0;
        for(k=0; k<2; k++)
            dx+= ((localCent[j][k] - localData[index][k]) * (localCent[j][k] - localData[index][k]));

        if(dx<dmin)            
        {  color = j;   
           dmin = dx;
        }
     }  
    keyMobj[index]   = color;
    valueMobj[index] = local_id[tx];
}

在上面的内核中,我分别从全局内存中获取结构 dataMobj 的前 8 个对象和 centMobj 的 2 个对象到本地内存 localData 和 localCent。就我的编程而言,我使用了正确的 for 循环来获取数据。

但它只让我正确执行前 8 个工作项(对于第一个工作组)。它不会使用剩余块的下一个剩余 8 个工作项来获取数据。

请告诉我这到底是如何工作的,如果我出错了,请告诉我。我还使用内存栅栏进行线程同步。

4

1 回答 1

3

该程序的问题是您超出了数组的范围。这就解释了为什么你可以只用 8 个工作项而不是 16 个工作项来获得正确的结果。

localDatalocal是内存空间中双精度数组的数组:

 __local double localData[8][2];

我们还有一个变量index,定义为:

int index = tx + bx*size;
//get_local_id(0) + get_group_id(0) * get_local_size(0) = get_global_size(0)

在 16 个工作项的情况下,索引的值范围为 [0-15]。在以下行:

dx+= ((localCent[j][k] - localData[index][k])
     * (localCent[j][k] - localData[index][k]));

即使本地数组的范围只能是 [0-8],也可以localData使用变量引用该变量。index

于 2013-01-28T22:02:44.483 回答