2012-02-28 2 views
3

У меня есть код, который имеет большое количество malloc и API-интерфейсов API-интерфейсов (я программирую на GPU, поэтому cudaMalloc).Последовательные распределители/деллалокаторы

В принципе, мой конец моего кода - это большой smorgasbord вызовов выделения, в то время как мой заключительный раздел - вызовы освобождения.

Поскольку я инкапсулировал свои глобальные данные в структуры, deallocations довольно длинные, но по крайней мере я могу разбить их на отдельную функцию. С другой стороны, я хотел бы получить более короткое решение. Кроме того, автоматический дезактиватор уменьшит риск утечек памяти, если я забуду явно написать освобождение в глобальной функции распределения.

Мне было интересно, можно ли написать какую-то шаблонную оболочку класса, которая может позволить мне «регистрировать» переменные во время процесса malloc/cudaMalloc, а затем в конце моделирования выполняются массовые петлевые освобождение (дерегистрация). Чтобы быть ясным, я не хочу набирать отдельные освобождения от деления (free/cudaFree), потому что снова это длинное и нежелательное, и предположение состояло бы в том, что все, что я регистрирую, не будет освобождено до тех пор, пока симуляция устройства не будет полной и основной заканчивается.

Выгода здесь заключается в том, что если я зарегистрирую новую переменную длительности моделирования, она автоматически освободится, так что нет никакой опасности, что я забыл освободить ее и создать утечку памяти.

Возможно ли такое обертывание?

Вы предложили бы это сделать?

Если да, то как?

Заранее благодарен!

+0

Старая проблема, но CUDA придает ей новый колорит. Интересно. –

+0

Вы согласны с ответами на C++ или были ли ваши теги «C» преднамеренными? – harrism

+0

Это должен быть C++. Первоначально проект был на C, но я добавил некоторые вещи STL на конечной стороне, так как он предлагает более чистый более простой контроль печати в моем сознании. Код устройства и распределение/освобождение являются традиционными C, хотя нет классов @ present. –

ответ

3

Идея:

Создать обе функции, один, который выделяет память и обеспечивает действительные указатели после их регистрации в «списке» выделенных указателей. Во втором методе, петля этот список и освобождает все указатели:

// ask for new allocated pointer that will be registered automatically in list of pointers. 
pointer1 = allocatePointer(size, listOfPointers); 
pointer2 = allocatePointer(size, listOfPointers); 

... 
// deallocate all pointers 
deallocatePointers(listOfPointers); 

Даже, вы можете использовать различные listOfPointers в зависимости от Вашей области моделирования:

listOfPointer1 = getNewListOfPointers(); 
listOfPointer2 = getNewListOfPointers(); 
.... 
p1 = allocatePointer(size, listOfPointer1); 
p2 = allocatePointer(size, listOfPointer2); 
... 
deallocatePointers(listOfPointers1); 
... 
deallocatePointers(listOfPointers2); 
1

Есть много способов кожи кошки, как и они говорят.

Я бы рекомендовал thrust's device_vector в качестве инструмента управления памятью. Он абстрагирует выделение, освобождение и memcpy в CUDA. Он также дает вам доступ ко всем алгоритмам, которые предоставляет Thrust.

Я бы не рекомендовал хранить случайные списки несвязанных указателей, как рекомендует Тио Пепе. Вместо этого вы должны инкапсулировать связанные данные в класс. Даже если вы используете thrust::device_vector, вы можете инкапсулировать несколько связанных векторов и операции над ними в класс.

+0

Но это C++? edit: Теперь я вижу, что CUDA поддерживает C++, но это не изначально. Во всяком случае, вопрос о C, но это может быть контроль над OP, конечно. –

+0

CUDA - C++. Он всегда поддерживал части C++ (например, шаблоны) и постепенно добавлял более полную поддержку. Я ничего не вижу в вопросе, который ограничивает его C. – harrism

+0

, может быть, но Wikipedia в любом случае говорит: «CUDA (с вычислительной способностью 1.x) использует безрекурсивное, не содержащее указателей подмножество языка C, плюс некоторые простые расширения ». Возможно, эти простые расширения были шаблонами, которые я не знаю. Вопрос помечен как «C», но, как я уже сказал, это может быть надзор со стороны OP. –

0

Лучшим выбором, вероятно, является использование интеллектуальных указателей из библиотеки ускорения C++, если это опция.

Если нет, лучшее, на что вы можете надеяться, в C - это дизайн программы, который позволяет вам писать распределение и освобождение в одном месте.Возможно, что-то вроде следующего псевдокода:

while(!terminate_program) 
{ 
    switch(state_machine) 
    { 
    case STATE_PREOPERATIONAL: 
     myclass_init(); // only necessary for non-global/static objects 
     myclass_mem_manager(); 
     state_machine = STATE_RUNNING; 
    break; 

    case STATE_RUNNING: 
     myclass_do_stuff(); 
     ... 
    break; 

    ... 

    case STATE_EXIT: 
     myclass_mem_manager(); 
     terminate_program = true; 
    break; 
    } 


void myclass_init() 
{ 
    ptr_x = NULL; 
    ptr_y = NULL; 

    /* Where ptr_x, ptr_y are some of the many objects to allocate/deallocate. 
    If ptr is a global/static, (static storage duration) it is 
    already set to NULL automatically and this function isn't 
    necessary */ 
} 

void myclass_mem_manager() 
{ 
    ptr_x = mem_manage (ptr_x, items_x*sizeof(Type_x)); 
    ptr_y = mem_manage (ptr_y, items_y*sizeof(Type_y)); 
} 


static void* mem_manage (const void* ptr, size_t bytes_n) 
{ 
    if(ptr == NULL) 
    { 
    ptr = malloc(bytes_n); 

    if (ptr == NULL) 
    {} // error handling 
    } 
    else 
    { 
    free(ptr); 
    ptr = NULL; 
    } 

    return ptr; 
}