使用 Thrust CUDA 对对象进行排序

Posted

技术标签:

【中文标题】使用 Thrust CUDA 对对象进行排序【英文标题】:Sorting objects with Thrust CUDA 【发布时间】:2011-07-14 00:20:07 【问题描述】:

是否可以使用 Thrust 库对对象进行排序? 我有以下结构:

struct OB
  int N;
  Cls *C; //CLS is another struct.

是否可以使用推力来根据 N 对 OB 数组进行排序?您能否提供一个使用推力对对象进行排序的简单示例?如果推力不能这样做,是否有任何其他 CUDA 库允许我这样做?

【问题讨论】:

【参考方案1】:

您可以通过重载 operator

__host__ __device__ struct Color
  double blue, green, red;
  double distance;
  void dist()
  
    distance = sqrt(blue*blue + green*green + red*red);
  
;

__host__ __device__ bool operator<(const Color &lhs, const Color &rhs) 

   return lhs.distance < rhs.distance;


int main(void)

   thrust::device_vector<Color> cd;
   thrust::host_vector<Color> ch;
   for (int i = 0; i<6; i++)
   
      Color c;
      c.blue = rand()*255;
      c.green = rand()*255;
      c.red = rand()*255;
      c.dist();
      ch.push_back(c);
   
   cd = ch;
   thrust::sort(cd.begin(), cd.end());
   ch = cd;
   return 0;

物体会按照距离排序。

【讨论】:

【参考方案2】:

即使您可以使用特殊的结构定义对对象进行排序,使用结构作为函子,它也会推动将排序算法从基数排序更改为合并排序。基数排序的速度明显快于合并排序。所以在使用推力的时候,尽量使用整数类型作为键值。

我建议你使用“thrust::sory_by_key(..)”函数。

您应该将结构从 AOS 更改为 SOA 结构。

struct OB
  int N;
  Cls *C; //CLS is another struct.

struct OBs
   int []Ns; -> thrust::device_vector<int> indices;
   Cls *C[]; -> thrust::device_vector<Cls> values;

当您使用 sort_by_key 对索引进行排序时,值已被排序。

thrust::sort_by_key(indices.begin(), indices.end(), values.begin());

【讨论】:

只是想知道,我怎么知道推力正在使用哪种排序算法? AFAIK,如果使用整数值,它们使用基数排序。如果使用用户定义的比较方法,则使用合并排序。如果使用浮点数,他们可能会再次使用合并排序。我记得我已经将浮点值转换(存储)为整数值以实现更好的排序性能。【参考方案3】:

thrust::sort 的文档显示它接受比较运算符。在他们的example 中查看这些是如何定义和使用的。我没有对此进行测试,但根据示例,您只需要一个看起来像这样的结构:

struct OBCmp 
  __host__ __device__
  bool operator()(const OB& o1, const OB& o2) 
      return o1.N < o2.N;
  
;

然后调用thrust::sort(obs.begin(), obs.end(), OBCmp())

【讨论】:

这应该被当作一个答案,我测试了它并且它有效。感谢您的帖子!【参考方案4】:

我还没有尝试过Thrust,但是CUDPP 中有一个类似的排序功能,叫做cudppSort。您不能使用 cudppSort 直接对结构进行排序,它只能处理整数或浮点数。

因此,对结构数组进行排序的一种方法是对(结构的)键和值的索引数组进行排序。稍后,使用排序索引数组将结构移动到它们最终排序的位置。我已经在博客文章here 中描述了如何为 cudppCompact 压缩算法执行此操作。 cudppSort 的技术也应该类似。

【讨论】:

【参考方案5】:

到目前为止,您无法对自定义对象进行排序。您可以进行基于键的排序,但不能像您提到的结构那样对自定义对象进行排序。还有一些其他基于开放式 CUDA 的算法可用于执行此操作,但这也需要进行一些修改等才能使它们为您工作。

【讨论】:

这是不正确的。有所有基本推力排序算法的版本,它们采用仿照 STL 严格弱排序二元谓词的函子。如果您在给定的用户对象上提供一个类似于此模型的仿函数,则排序将正常工作。

以上是关于使用 Thrust CUDA 对对象进行排序的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Thrust 库以较低的精度对键进行排序

您如何构建示例 CUDA 推力设备排序?

CUDA/thrust 中分段数据的成对操作

CUDA:如何在 GPU 上直接使用推力::sort_by_key? [复制]

CUDA Thrust 大幅减少

在thrust::device_vector (CUDA Thrust) 上的thrust::min_element 崩溃