我有一个由推力使用的仿函数,我需要动态指定它的长度,比如
struct func {
const int h;
func(const int _h): h(_h) {}
__device__ __host__
void operator()(int id) {
double data[h];
}
};
我不知道该怎么做,因为h必须是一个已知的数字,但直到运行时才知道。
答案 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实际上支持堆内存的动态分配)。