运行OpenCL时程序停止

时间:2015-08-18 18:38:01

标签: multithreading opencl knn

OpenCL代码如下:

typedef struct {
    float record[8];
    float dis;
    int t_class;
}node;

float Dist ( __global float * a , __global float * b , int width ) {
    float rst = 0;

    for (int i =0; i < width; i++){
        rst += (a[i] - b[i])*(a[i] - b[i]);
    }

    return sqrt(rst);
}


__kernel void ex_knn ( __global node * in_data , __global node * in_data_copy, int num_record , int num_feature, __global float * new_point , int k , __global node * rst )
{
    int idx = get_global_id(0);

    for(int i=0;i<4177;i++){
        in_data_copy[idx*4177 + i] = in_data[i];
    }

    for (int i=0; i < num_record; i++){
        in_data_copy [idx*4177 + i ]. dis = Dist ( in_data_copy [idx*4177 +  i ]. record , new_point , num_feature );
    }

    node tmp;
    for (int i=0; i< num_record-1;i++)
        for (int j =0; j<num_record-i-1; j++)
        {
            if ( in_data_copy [ idx*4177 + j ]. dis > in_data_copy [idx*4177 + j + 1 ]. dis )
            {
                tmp = in_data_copy [ idx*4177 + j ];
                in_data_copy [ idx*4177 + j ] = in_data_copy [ idx*4177 + j + 1 ];
                in_data_copy [ idx*4177 + j + 1 ] = tmp ;
            }
        }

    for (int i=0;i<k;i++)
        rst [ idx * k + i ] = in_data_copy [ idx*4177 + i ];

}

我发现此代码段错误,但我不知道为什么。 基本上,它是一种在多个线程上运行数据集副本的knn方法。 in_data_copy是多个数据集副本的全局内存部分。这意味着,每个单个线程都有一个数据集副本。 然后我做了详尽的knn方法,计算距离和排序。

我知道这里可能存在竞争条件,一些线程可能会计算距离,而其他一些线程可能会进行交换。然而,这些线程正在处理'in_data_copy'的不同块,这有关系吗?

当我运行程序时,交换前的所有代码都正确运行。 进入交换时,OpenCL代码停在某处并退出程序。知道为什么会这样吗?

1 个答案:

答案 0 :(得分:1)

假设你没有超出Dist()in_data_copy范围内的界限,结构对齐很可能就是问题所在。您需要将结构与2尺寸的下一个幂对齐。目前您的结构大小为40字节,下一次2的幂为64字节。您可以通过在顶部添加6个4字节元素数组或在底部添加6个4字节成员来填充结构。第二个选项可能如下所示:

typedef struct {
    float record[8];
    float dis;
    int t_class;
    int pad1;
    int pad2;
    int pad3;
    int pad4;
    int pad5;
    int pad6;
}node;

注意:重要的是要将结构从最宽的类型首先声明为最窄的,以避免使用未使用的空间和不同设备上的不同对齐方式的潜在问题。