使用基数排序排序1位数组?

时间:2014-05-31 16:04:40

标签: c++ cuda thrust

我有一个bool数组&#34;一个标记数组存储为char *&#34; 我想使用基数排序对它进行有效排序,据我所知,基数排序复杂度为O(#bits N),对于char *为O(8N),对于bool *为O(N)(如果存在)< / p>

我尝试过push :: stable_sort_by_key,在我的设备上排序2 ^ 21 char指针需要1.7 ms 另一项测试是仅对第一位使用比较函数:

struct OBCmp {
    __host__ __device__
    bool operator()(const char& o1, const char& o2) {
        return (o1 & 1) < (o2 & 1);
    }
};

使用thrust::stable_sort_by_key(d_vec.begin(), d_vec.end(), d_vec_values.begin(), OBCmp ());的结果时间是9毫秒

但我几乎可以肯定它已经使用了另一种算法&#34;而不是基数排序&#34;,我的猜测是如果我可以使基数排序只使用第一位,那么时间应该是大约0.3毫秒

任何提示如何做到这一点? &#34;甚至手动没有推力&#34;

2 个答案:

答案 0 :(得分:3)

简单的丑陋C?

#include <stdlib.h>
#include <stdio.h>

#define SIZE 100

void sort(char* my_array, int size)
{
    int counter = 0;

    for (int i = 0; i < size; i++, counter += (my_array[i] == 1));

    for (int i = 0; i < counter; i++, my_array[i] = 1);

    for (int i = counter; i < size; i++, my_array[i] = 0);
}

int main()
{
    char* my_array = malloc(SIZE * sizeof(char));

    for (int i = 0; i < SIZE; i++)
    {
        my_array[i] = (((i + 43) * (i + 17)) % 677) & 1; //Thought less than 0.5s too garantee randomness of chosen numbers
    }

    sort(my_array, SIZE);

    return 0;
}

答案 1 :(得分:2)

我建议计算一个(或零),然后根据它创建解决方案向量。这是一个使用推力的实例:

$ cat t427.cu
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/sort.h>
#include <thrust/count.h>
#include <stdio.h>
#include <stdlib.h>

#define DSIZE (1<<21)
int main(){
  cudaEvent_t start, stop;
  float et;
  cudaEventCreate(&start); cudaEventCreate(&stop);
  thrust::host_vector<char> h_data(DSIZE);
  for (int i = 0; i < DSIZE; i++) h_data[i] = rand()%2;
  thrust::device_vector<char> d_data = h_data;
  cudaEventRecord(start);
  thrust::sort(d_data.begin(), d_data.end());
  cudaEventRecord(stop);
  cudaEventSynchronize(stop);
  cudaEventElapsedTime(&et, start, stop);
  printf("Sort time: %fms\n", et);
  thrust::device_vector<char> d2_data = h_data;
  thrust::device_vector<char> d3_data(DSIZE);
  cudaEventRecord(start);
  int zeroes = thrust::count(d2_data.begin(), d2_data.end(), 0);
  thrust::fill(d3_data.begin(), d3_data.begin()+zeroes, 0);
  thrust::fill(d3_data.begin() + zeroes, d3_data.end(), 1);
  cudaEventRecord(stop);
  cudaEventSynchronize(stop);
  cudaEventElapsedTime(&et, start, stop);
  printf("count/fill time: %fms\n", et);
  if (thrust::equal(d_data.begin(), d_data.end(), d3_data.begin())) printf("Success!\n");
  else printf("Failure\n");
  return 0;
}

$ nvcc -O3 -arch=sm_20 -o t427 t427.cu
$ ./t427
Sort time: 1.450560ms
count/fill time: 0.302656ms
Success!
$