我要生成的CUDA一些决策树,下面我们就伪码Genarating决策树(代码是非常原始的,它只是为了解我写的):对CUDA
class Node
{
public :
Node* father;
Node** sons;
int countSons;
__device__ __host__ Node(Node* father)
{
this->father = father;
sons = NULL;
}
};
__global__ void GenerateSons(Node** fathers, int countFathers*, Node** sons, int* countSons)
{
int Thread_Index = (blockDim.x * blockIdx.x) + threadIdx.x;
if(Thread_Index < *(countFathers))
{
Node* Thread_Father = fathers[Thread_Index];
Node** Thread_Sons;
int Thread_countSons;
//Now we are creating new sons for our Thread_Father
/*
* Generating Thread_Sons for Thread_Father;
*/
Thread_Father->sons = Thread_Sons;
Thread_Father->countSons = Thread_countSons;
//Wait for others
/*I added here __syncthreads because I want to count all generated sons
by threads
*/
*(countSons) += Thread_countSons;
__syncthreads();
//Get all generated sons from whole Block and copy to sons
if(threadIdx.x == 0)
{
sons = new Node*[*(countSons)];
}
/*I added here __syncthreads because I want to allocated array for sons
*/
__syncthreads();
int Thread_Offset;
/*
* Get correct offset for actual thread
*/
for(int i = 0; i < Thread_countSons; i++)
sons[Thread_Offset + i] = Thread_Sons[i];
}
}
void main()
{
Node* root = new Node();
//transfer root to kernel by cudaMalloc and cudaMemcpy
Node* root_d = root->transfer();
Node** fathers_d;
/*
* preapre array with father root and copy him to kernel
*/
int* countFathers, countSons;
/*
* preapre pointer of int for kernel and for countFathers set value 1
*/
for(int i = 0; i < LevelTree; i++)
{
Node** sons = NULL;
int threadsPerBlock = 256;
int blocksPerGrid = (*(countFathers)/*get count of fathers*/ + threadsPerBlock - 1)/threadsPerBlock;
GenerateSons<<<blocksPerGrid , threadsPerBlock >>>(fathers_d, countFathers, sons, countSons);
//Wait for end of kernel call
cudaDeviceSynchronize();
//replace
fathers_d = sons;
countFathers = countSons;
}
}
所以,适用于5级(为跳棋生成决策树),但在6级上我有错误。在内核代码的某个地方,malloc返回NULL
,对我来说,这是blockThreads中的某些线程无法分配更多内存的信息。我非常肯定,我正在清理所有我不需要的对象,在调用内核的每一端。我在想,我无法理解CUDA中使用内存的一些事实。如果我在线程的本地内存中创建对象,并且内核结束了他的活动,那么在内核的secound开始时,我可以看到内核的第一个调用的节点是。所以我的问题是第一次调用内核的对象Node
在哪里存储?它们是否存储在线程的本地内存中?所以如果这是真的,那么在每次调用我的内核函数时,我会减少此线程的本地内存空间?
对不起,我的英文不好,如果有什么不清楚。
我使用GT555米计算能力2.1,CUDA SDK 5.0,Visual Studio 2010中的高级与NSight 3.0
你在内核中调用new并且从不调用delete。由于您正在使用____global___ void GenerateSons,我敢打赌,您在设备上的内存不足。 – AlexLordThorsen 2013-02-23 10:41:45
好吧,我的设备有2Gb的空间,并且sizeof(Node)= 28。首先调用genrate 7个儿子,secound 49,next 379和最后的正确调用2769.因此,我的设备生成了3204个儿子,产生87Kb? – waskithebest 2013-02-23 11:19:44
嗯,我想知道新的内存是否从共享内存拉出。我将不得不查阅文档。 – AlexLordThorsen 2013-02-23 14:09:36