前一段时间我写了下面的代码,做类似的事情:
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <stdlib.h>
__global__ void fast_finder(unsigned int *g_found, float x, float *y)
{
unsigned int i = blockIdx.x * blockDim.x + threadIdx.x;
unsigned int pos = (unsigned int)(x == y[i]);
g_found[i * (1 - pos)] = i * pos;
}
int main(int argc, char *argv[])
{
int N = 65536;
unsigned int h_found, *d_found;
float *h_y = (float *)malloc(N * sizeof(float)), *d_y, x = 5.0f;
int nThreads = 1024, nBloks = N/nThreads;
for (int i = 0; i < N; ++i) h_y[i] = (float)(N - i - 1);
if (x != h_y[0]) {
cudaSetDevice(0);
cudaMalloc((void **)&d_found, N * sizeof(unsigned int));
cudaMalloc((void **)&d_y, N * sizeof(float));
cudaMemcpy(d_y, h_y, N * sizeof(float), cudaMemcpyHostToDevice);
fast_finder<<<nBloks, nThreads>>>(d_found, x, d_y);
cudaThreadSynchronize();
cudaMemcpy(&h_found, d_found, sizeof(unsigned int), cudaMemcpyDeviceToHost);
if (h_found) printf("%g found on %d. position!\n", x, h_found);
else printf("%g not found!\n", x);
cudaFree(d_y);
cudaFree(d_found);
} else printf("%g found on the first position!\n", x);
free(h_y);
getchar();
return EXIT_SUCCESS;
}
这里每个线程检查由全局线程指数y
提供的值等于x
。如果它是真的,则线程将其索引写入g_found
数组的第一个位置,否则将0写入其索引提供的g_found
的位置。对于长度为16的y
,在第11位包含在y
值5的 出来如下:
g_found = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
在这种情况下y
不需要被排序,但必须只包含唯一值。此代码可伊斯利改变为一个发现其中提供x
将被插入(设备部件)指数,如下:这个版本
__global__ void fast_finder(unsigned int *g_found, float x, float *y)
{
unsigned int i = blockIdx.x * blockDim.x + threadIdx.x;
unsigned int pos = (unsigned int)(x >= y[i] || x <= y[i+1]);
g_found[i * (1 - pos)] = (i + 1) * pos;
}
输出将类似于矿。当位置0处的g_found
为0时,x
的值不存在于阵列y
中。在内核被调用之前,通过主机代码检查y
的第一个元素是否等于x
。改变这个部分也不是一个问题,也不适用于你想要的条件。
正如您所看到的,在这样的解决方案中,所有线程一起工作,并且不需要任何执行终止,只要找到x
即可。好的事情也将是申请包搜索,意思是一个线程寻找y
的一小部分,因此允许y
要大得多。
除非已排序的向量已经存在于设备内存中,否则对此使用CUDA是没有意义的。 CPU上的二进制搜索具有复杂性log2 n。 – RoBiK 2013-03-07 10:16:16
您可能对[thrust :: lower_bound]感兴趣(http://thrust.github.com/doc/group__binary__search.html)或[thrust :: partition_point](http://thrust.github.com/doc/group__searching .html#ga1b61bfe7c810941e02b723e050c805ba)如果你不熟悉推力,有一个[入门指南](https://github.com/thrust/thrust/wiki/Quick-Start-Guide)。 – 2013-03-07 16:10:32