前一段時間我寫了下面的代碼,做類似的事情:
#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