首次在CUDA中搜索

时间:2013-06-11 14:13:55

标签: search cuda gpu

我的应用程序在device-code中执行了一些操作,并在kernel内生成了一个数组。

我需要搜索此数组中第一次出现的元素。我怎样才能在GPU中执行它?如果我将数组复制到CPU并在那里工作,它将产生如此多的内存流量,因为这段代码被多次调用。

2 个答案:

答案 0 :(得分:1)

最有可能是更复杂的解决方案,但是首先,特别是如果元素的出现次数非常少,那么简单的暴力原子能可能是一个可行的解决方案:

template<typename T> __global__ void find(T *data, T value, int *min_idx)
{
    int idx = threadIdx.x + blockDim.x*blockIdx.x;
    if(data[idx] == value)
        atomicMin(min_idx, idx);
}

如果出现的次数确实很小,因此几乎所有线程甚至都没有尝试访问原子,这实际上可能并不是一个糟糕的解决方案。否则(如果搜索到的元素不是那么罕见),你会有更多的内部内部发散,更糟糕的是,原子操作发生冲突的概率要高得多。


编辑:对于更复杂的方法(但可能仍然不是最好的方法),否则您也可以在预步骤中创建一个int数组,其值为索引{{1如果输入数组的元素等于该索引处的搜索元素,则设置为idx,如果不匹配,则设置为idx

INT_MAX

然后对该索引数组执行“经典”最小约简以获得第一个匹配索引。

答案 1 :(得分:0)

一种方法是使用atomic操作,阻止其他线程访问可编辑数据,直到当前正在处理的数据完成为止。

以下是查找单词首次出现的示例: http://supercomputingblog.com/cuda/search-algorithm-with-cuda/ 在该示例中使用atomicMin函数。此外,文章中还有GPU和CPU之间的性能比较。

查找第一次出现的另一种方法是使用称为并行缩减的方法。 CUDA SDK中有一个并行求和的示例(该示例计算数组中所有值的总和)。并行缩减是一个很好的选择,特别是如果您使用具有较旧计算能力版本的硬件并且需要高精度。

要使用并行缩减查找第一次出现,首先要检查数组中的值是否等于您要查找的值。如果是,则保存其索引。然后,执行一个或多个min操作(非原子最小值),您可以在其中比较上一步中保存的索引。您可以通过编辑CUDA SDK的并行总和示例来实现此搜索。

This site提供了有关缩减和原子操作的一些信息。它还包括我在这里没有谈到的二叉树缩减和变通原子函数。

还讨论了原子与减少问题on Stack Overflow