我有一个代码,其中包含大量的malloc
s和设备特定的API mallocs(我在GPU上编程,所以cudaMalloc
)。
基本上,我的代码开头的末尾是分配调用的大杂烩,而我的结束部分是deallocation调用。
由于我已经将全局数据封装在结构中,所以释放相当长,但至少我可以将它们分解为一个单独的函数。另一方面,我想要一个更短的解决方案。此外,如果我忘记在全局分配器函数中显式写入释放,那么自动释放程序将降低内存泄漏的风险。
我想知道是否可以编写某种模板化的类包装器,允许我在malloc
/cudaMalloc
过程中"注册"变量,然后在模拟结束时进行基于大规模循环的解除分配(注销)。需要明确的是,我不想键入单独的解除分配(free
/cudaFree
s),因为这也是长时间的,也是不希望的,并且假设在设备模拟完成并且main终止之前,我注册的任何东西都不会被解除分配。
这里的一个好处是,如果我注册了一个新的模拟持续时间变量,它将自动解除分配,所以我不会忘记解除分配并造成内存泄漏。
这样的包装物可能吗?
你会建议这样做吗?
如果是,如何?
提前感谢!
一个想法:
创建两个函数,一个分配内存并在将它们注册到已分配指针的"列表"中后提供有效指针的函数。在第二种方法中,循环此列表并解除分配所有指针:
// 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);
正如他们所说,有很多方法可以剥猫的皮。
我推荐使用thrust的device_vector作为内存管理工具。它抽象了CUDA中的分配、释放和内存。它还允许您访问Thrust提供的所有算法。
我不建议像蒂奥·佩佩建议的那样,随意列出不相关的指针。相反,您应该将相关数据封装到一个类中。即使使用thrust::device_vector
,也可能希望将多个相关向量及其操作封装到一个类中。
如果可以的话,最好的选择可能是使用C++boost库中的智能指针。
如果没有,那么在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;
}