2012-01-27 55 views
4

我正在评估CUDA并正在使用Thrust库对数字进行排序。快速CUDA推力自定义比较运算符

我想为推力::排序创建我自己的比较器,但它会大大减慢速度! 我创建了我自己的减去通过从functional.h复制代码实现。然而,它似乎是以其他方式编译的,而且工作速度非常缓慢。

  1. 默认的比较:推力::以下() - 毫秒
  2. 我自己比较器:以下() - 毫秒

我使用Visual Studio 2010的什么我应该怎么做才能获得与选项1相同的性能?

完整代码:

#include <stdio.h> 

#include <cuda.h> 

#include <thrust/host_vector.h> 
#include <thrust/device_vector.h> 
#include <thrust/generate.h> 
#include <thrust/sort.h> 

int myRand() 
{ 
     static int counter = 0; 
     if (counter++ % 10000 == 0) 
       srand(time(NULL)+counter); 
     return (rand()<<16) | rand(); 
} 

template<typename T> 
struct less : public thrust::binary_function<T,T,bool> 
{ 
    __host__ __device__ bool operator()(const T &lhs, const T &rhs) const { 
    return lhs < rhs; 
    } 
}; 

int main() 
{ 
    thrust::host_vector<int> h_vec(10 * 1000 * 1000); 
    thrust::generate(h_vec.begin(), h_vec.end(), myRand); 

    thrust::device_vector<int> d_vec = h_vec; 

    int clc = clock(); 
    thrust::sort(d_vec.begin(), d_vec.end(), less<int>()); 
    printf("%dms\n", (clock()-clc) * 1000/CLOCKS_PER_SEC); 

    return 0; 
} 
+0

好奇,如果你已经尝试ArrayFire的排序功能。可能对你的分析有用。 – arrayfire 2012-01-28 01:54:51

回答

6

你观察性能差异的原因是因为推力正在实施与排序依据提供给thrust::sort的参数不同的算法。

在案例1中,Thrust可以证明这种排序可以用基数排序的线性时间实现。这是因为要排序的数据类型是内置数值类型(int),并且比较函数是内置小于操作 - 推力识别thrust::less<int>将产生与x < y等效的结果。

在情况2,推力知道也不关心你的用户提供less<int>,并有使用基于一个比较排序具有不同的渐近复杂性,即使在真理的less<int>相当于thrust::less<int>更保守的算法。

通常,用户定义的比较运算符不能用于处理数据二进制表示(例如基数排序)的更严格,更快速的排序。在这些情况下,Thrust会回到更一般的,但更慢的排序。