Я хочу, чтобы сгенерировать дерево решений на 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. Если я создаю объект в локальной памяти потока, а ядро заканчивает его действие, то в начале ядра я вижу, что узлы от первого вызова ядра. Итак, мой вопрос в том, где хранятся объекты Node
от первого вызова ядра? Сохраняются ли они в локальной памяти потока в блоке? Итак, если это правда, то при каждом вызове моей функции ядра я уменьшу пространство локальной памяти этого потока?
Извините за мой плохой английский, если что-то неясно.
Я использую GT 555M с Compute возможностями 2.1, CUDA SDK 5.0, Visual Studio 2010 Premium с Nsight 3,0
Вы вызываете новое в ядре и никогда не вызываете delete. Поскольку вы используете ____global____ void GenerateSons, я готов поспорить, что на устройстве у вас заканчивается память. – AlexLordThorsen
Хорошо, мое устройство имеет 2 ГБ пространства и sizeof (Node) = 28. Первый вызов genrate 7 сыновей, секунд 49, следующий 379 и последний правильный вызов 2769. Итак, мое устройство сгенерировало 3204 сыновей, которые дают 87Kb ??? – waskithebest
hmmm, мне интересно, если новый вытаскивает память из разделяемой памяти. Мне придется искать документацию. – AlexLordThorsen