阵列推力动态内存分配

thrust dynamic memory allocation for array

本文关键字:内存 分配 动态 阵列      更新时间:2023-10-16

我有一个由推力使用的函子,我需要动态指定它的长度,就像一样

struct func { 
       const int h;
       func(const int _h): h(_h) {}
       __device__ __host__
       void operator()(int id) {
              double data[h];
      }
};

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

解决这个问题的明显方法是使用动态内存分配,因此函子变成

   __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。不利的一面是,内存分配将在全局内存的运行时堆上,这限制了编译器的优化,而且新的/自由的运算符本身非常慢,因此在内核启动中的每个线程都会发生这种情况,这将耗费大量性能。

另一种选择是,如果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实际上支持堆内存的动态分配)。