OpenCL - 内核运行缓慢

时间:2013-09-13 19:18:47

标签: select kernel opencl

我的内核非常简单。它会尝试查看代码是否有效,然后根据前缀扫描输出仅存储唯一代码:

__kernel void moveValid(__global int* sortCode, __global int* mark, __global int* processorOffsets, __global int* uniqueCode,__global int* numPoints, __global int* pointIndex) 
{
    int ig = get_global_id(0);
    int m = mark[ig];
    int j= processorOffsets[ig];
    atomic_inc(&numPoints[j-1]);
    // select
    if(m == true)
    {   
            uniqueCode[j] = sortCode[ig];
            pointIndex[j] = ig;
    }

    barrier(CLK_GLOBAL_MEM_FENCE);
}

好像内核真的很慢。这是由于if声明吗?谁能提供关于如何改进内核的任何提示?也可以选择在这种情况下使用吗?

1 个答案:

答案 0 :(得分:2)

因此,如果不深入研究您的代码,我可以就其速度提供以下反馈。我假设你使用GPU作为你的设备。如果您使用CPU作为设备,则有些信息可能仍然适用。

  

atomic_inc(安培;为NumPoints [J-1]);

在大多数设备上,原子增量对于全局内存来说非常慢。这是因为必须将数据提交到全局内存(不能在本地缓存)。

  

屏障(CLK_GLOBAL_MEM_FENCE);

此屏障确保work_group中的所有work_items在继续执行之前都存在。为什么在代码中需要这个?特别是当没有什么可做的时候,没有理由不让你的线程完成执行。这也是一个很大的表现。

  

if(m == true)

这实际上并不是我见过的最糟糕的声明,因为它只有一个分支。这仍然会减慢您的代码速度,但不会像其他东西那样大。在继续之前,将为串行中的所有线程(对于某些体系结构)计算条件。

总的来说,在这段代码中,您将执行4次全局内存访问,就像原子操作一样,没有数学运算。 GPU是执行此类算法的最差设备类型,因为内存访问对全局内存的速度特别慢,尤其是在访问合并时。你能考虑将一些阵列转移到本地内存吗?