我的内核非常简单。它会尝试查看代码是否有效,然后根据前缀扫描输出仅存储唯一代码:
__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声明吗?谁能提供关于如何改进内核的任何提示?也可以选择在这种情况下使用吗?
答案 0 :(得分:2)
因此,如果不深入研究您的代码,我可以就其速度提供以下反馈。我假设你使用GPU作为你的设备。如果您使用CPU作为设备,则有些信息可能仍然适用。
atomic_inc(安培;为NumPoints [J-1]);
在大多数设备上,原子增量对于全局内存来说非常慢。这是因为必须将数据提交到全局内存(不能在本地缓存)。
屏障(CLK_GLOBAL_MEM_FENCE);
此屏障确保work_group中的所有work_items在继续执行之前都存在。为什么在代码中需要这个?特别是当没有什么可做的时候,没有理由不让你的线程完成执行。这也是一个很大的表现。
if(m == true)
这实际上并不是我见过的最糟糕的声明,因为它只有一个分支。这仍然会减慢您的代码速度,但不会像其他东西那样大。在继续之前,将为串行中的所有线程(对于某些体系结构)计算条件。
总的来说,在这段代码中,您将执行4次全局内存访问,就像原子操作一样,没有数学运算。 GPU是执行此类算法的最差设备类型,因为内存访问对全局内存的速度特别慢,尤其是在访问合并时。你能考虑将一些阵列转移到本地内存吗?