我正在研究一项遗传计划,其中将一些繁重的工作移植到CUDA中。 (以前只是OpenMP)。
它的运行速度不是很快,而且我收到了与递归相关的错误:
输入功能'_Z9KScoreOnePdPiS_S_P9CPPGPNode'的堆栈大小无法静态确定
我添加了一个在CUDA上运行的逻辑块。我相信它足以说明它是如何工作的。我很高兴听到我可以添加的其他优化,但我真的想接受递归,如果它会加快速度。
非常欢迎如何实现这一目标的例子。
__device__ double Fadd(double a, double b) {
return a + b;
};
__device__ double Fsubtract(double a, double b) {
return a - b;
};
__device__ double action (int fNo, double aa , double bb, double cc, double dd) {
switch (fNo) {
case 0 :
return Fadd(aa,bb);
case 1 :
return Fsubtract(aa,bb);
case 2 :
return Fmultiply(aa,bb);
case 3 :
return Fdivide(aa,bb);
default:
return 0.0;
}
}
__device__ double solve(int node,CPPGPNode * dev_m_Items,double * var_set) {
if (dev_m_Items[node].is_terminal) {
return var_set[dev_m_Items[node].tNo];
} else {
double values[4];
for (unsigned int x = 0; x < 4; x++ ) {
if (x < dev_m_Items[node].fInputs) {
values[x] = solve(dev_m_Items[node].children[x],dev_m_Items,var_set);
} else {
values[x] = 0.0;
}
}
return action(dev_m_Items[node].fNo,values[0],values[1],values[2],values[3]);
}
}
__global__ void KScoreOne(double *scores,int * root_nodes,double * targets,double * cases,CPPGPNode * dev_m_Items) {
int pid = blockIdx.x;
// We only work if this node needs to be calculated
if (root_nodes[pid] != -1) {
for (unsigned int case_no = 0; case_no < FITNESS_CASES; case_no ++) {
double result = solve(root_nodes[pid],dev_m_Items,&cases[case_no]);
double target = targets[case_no];
scores[pid] += abs(result - target);
}
}
}
我无法使任何堆栈示例适用于大型树结构,这就是解决的问题。
答案 0 :(得分:0)
我现在已经解决了这个问题。将递归参数放入堆栈并不是一个例子,但它是一个非常相似的系统。
作为节点树创建的一部分,我将每个节点都附加到一个向量中。我现在使用http://en.wikipedia.org/wiki/Reverse_Polish_notation反向解决问题,这非常适合每个节点包含要执行的值或函数。
它也比递归版快〜20%,所以我很高兴!