CPU 바이너리 검색 속도를 높이려고합니다. 불행히도, GPU 버전은 항상 CPU 버전보다 훨씬 느립니다. 아마도이 문제는 GPU에 적합하지 않거나 잘못된 것이 있습니까?CUDA 바이너리 검색 구현
CPU 버전 (약 0.6ms.) : 길이 2000 정렬 된 배열을 사용하여 특정 값을
...
Lookup (search[j], search_array, array_length, m);
...
int Lookup (int search, int* arr, int length, int& m)
{
int l(0), r(length-1);
while (l <= r)
{
m = (l+r)/2;
if (search < arr[m])
r = m-1;
else if (search > arr[m])
l = m+1;
else
{
return index[m];
}
}
if (arr[m] >= search)
return m;
return (m+1);
}
GPU 버전을 바이너리 검색을 수행 (약 20ms의.) : 의 길이는 2000 정렬 된 배열을 사용하여 특정 값에 대한 이진 검색
....
p_ary_search<<<16, 64>>>(search[j], array_length, dev_arr, dev_ret_val);
....
__global__ void p_ary_search(int search, int array_length, int *arr, int *ret_val)
{
const int num_threads = blockDim.x * gridDim.x;
const int thread = blockIdx.x * blockDim.x + threadIdx.x;
int set_size = array_length;
ret_val[0] = -1; // return value
ret_val[1] = 0; // offset
while(set_size != 0)
{
// Get the offset of the array, initially set to 0
int offset = ret_val[1];
// I think this is necessary in case a thread gets ahead, and resets offset before it's read
// This isn't necessary for the unit tests to pass, but I still like it here
__syncthreads();
// Get the next index to check
int index_to_check = get_index_to_check(thread, num_threads, set_size, offset);
// If the index is outside the bounds of the array then lets not check it
if (index_to_check < array_length)
{
// If the next index is outside the bounds of the array, then set it to maximum array size
int next_index_to_check = get_index_to_check(thread + 1, num_threads, set_size, offset);
if (next_index_to_check >= array_length)
{
next_index_to_check = array_length - 1;
}
// If we're at the mid section of the array reset the offset to this index
if (search > arr[index_to_check] && (search < arr[next_index_to_check]))
{
ret_val[1] = index_to_check;
}
else if (search == arr[index_to_check])
{
// Set the return var if we hit it
ret_val[0] = index_to_check;
}
}
// Since this is a p-ary search divide by our total threads to get the next set size
set_size = set_size/num_threads;
// Sync up so no threads jump ahead and get a bad offset
__syncthreads();
}
}
더 큰 배열을 사용해도 시간 비율은 더 좋지 않습니다.
간단한 이진 검색은 GPU 작업에 적합하지 않습니다. 병렬화 할 수없는 직렬 연산입니다. 그러나 배열을 작은 덩어리로 나눌 수 있으며 각 배열에서 이진 검색을 수행 할 수 있습니다. X 청크를 만들어 X 병렬 스레드에서 변수를 포함할지 결정합니다. 후보자를 제외한 모든 사람을 버리고 더 세분화합니다. –
http://wiki.thrust.googlecode.com/hg/html/group__binary__search.html에서 추력 2 진수 검색을 확인하십시오. – jmsu