数组的推力动态内存分配

时间:2013-12-10 06:35:41

标签: c++ cuda thrust

我有一个由推力使用的仿函数,我需要动态指定它的长度,比如

struct func { 

       const int h;

       func(const int _h): h(_h) {}

       __device__ __host__
       void operator()(int id) {
              double data[h];
      }
};

我不知道该怎么做,因为h必须是一个已知的数字,但直到运行时才知道。

1 个答案:

答案 0 :(得分:2)

解决这个问题的显而易见的方法是使用动态内存分配,因此函数变为

   __device__ __host__
   void operator()(int id) {
        double *data  = new double[h];

        // functor code goes here

        // Heap memory has context scope, so delete is necessary to stop leaks
        delete[] data; 
   };

这适用于2.0或更高版本的计算能力的GPU。缺点是内存分配将在全局memoey中的运行时堆上,这限制了编译器优化,而新/自由运算符本身非常慢,因此在内核启动中对每个线程发生这种情况将花费大量性能。

另一种选择,如果h的值范围有限,请考虑使用模板参数替换运算符代码中的h,然后仅使用选择器代替已知情况,如

   template<int j>
   __device__ __host__
   void guts(int id) {
       double data[j];
       // code here
   };

   __device__ __host__
   void guts_rt(int id) {
       double *data = new double[h];
       // code here
       delete[] data;
   };

   __device__ __host__
   void operator()(int id) {
       switch (h) {
           case 2:
           guts<2>(id);
           break;

           case 4:
           guts<4>(id);
           break;

           // As many as needed here

           default:
           guts_rt(id);
           break;
      }
  }

即。尽可能尝试使用硬编码数组(编译器可以优化),否则回到动态解决方案(如果你的GPU实际上支持堆内存的动态分配)。