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

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

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

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

【问题讨论】:

    标签: sorting cuda thrust cudpp


    【解决方案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 严格弱排序二元谓词的函子。如果您在给定的用户对象上提供一个类似于此模型的仿函数,则排序将正常工作。
        猜你喜欢
        • 2016-11-07
        • 1970-01-01
        • 2015-03-24
        • 1970-01-01
        • 1970-01-01
        • 2013-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多