CUDA:在排序函数中使用Comparator时,Thrust如何管理内存?

时间:2013-06-23 11:16:04

标签: sorting cuda gpu thrust gpu-programming

我有一个10个字符的char array我希望将其作为参数传递给比较器,该比较器将由Thrust的排序函数使用。

为了为这个数组分配内存,我使用cudaMalloc。但是cudaMalloc在全局内存中分配内存,因此每当线程想要从该数组中读取数据时,它就必须访问全局内存。

但是这个数组很小,我相信如果将它存储到某个共享内存甚至每个线程的寄存器中会更有效。但是,有可能通过推力实现这一点,如果是,如何?

这是比较器:

struct comp{
   int *data_to_sort;
   char *helpingArray;

   comp(int *data_ptr) this->data_to_sort = data_ptr;

   __host__ __device__
      bool operator()(const int&a, const int&b){

            //use helpingArray to do some comparisons and
           // return true/false accordingly

      }
 }

然后我为全局内存中的helpingArray分配内存,并将其作为参数传递给Comparator结构到排序函数。

请注意,data_to_sort数组存储在全局内存中,因为它包含需要排序的数据,我们无法避免这种情况发生。

这很好用,排序方法比cpu排序方法快,但我相信如果我避免将helpingArray存储在全局内存中,排序方法会变得更快。

1 个答案:

答案 0 :(得分:1)

我同意将helpingArray置于全局内存中毫无意义,并且至少在一定程度上降低了性能。执行内核的推力后端是“关闭”的,不会暴露内核级功能,如共享内存或寄存器,因此无法直接使用。

话虽如此,你可以做两件事来改善这一点。第一个是宣布你的仿函数:

struct comp{
   char helpingArray[10];

   __host__ __device__
      bool operator()(const int&a, const int&b){ ... }
 }

您可以在将函数传递给正在使用的推力算法之前在主机代码中填充helpingArray(请注意,仿函数通过传递,因此这是完全合法的)。在这种情况下,helpingArray可能会在线程本地内存中出现。这样做可能会或可能不会有性能提升。当然,它极大地简化了支持事物所需的主机代码。

另一种选择是在__constant__内存中声明helpingArray并在functor中引用它。 如果每个线程的访问模式是统一的,那么由于常量缓存,可能会有性能提升。