Bootstrap

CUDA与内存池(一):内存池

我正在尝试搞一个物理引擎,计划先用常规的技术实现,将来弄到GPU上以获得更高的性能。那么,虽然现在只是在本机上面运行,最好能够做一些往CUDA上面移植的准备,以减少将来的工作量。

GPGPU计算有个显著的特点:它是异构的,相当于同时操纵两台电脑。这两个东西各自有一套内存,通过几个cuda函数进行内存交互。于是就产生了地址的问题。考虑下面的代码:

class Foo {};
class Bar
{
    Foo* member;
};

如果我把一个Bar实例传到显卡上,那么里面的member成员所指向的地址很可能是无效的,因为显卡相当于另一台电脑:在另一台电脑上仍然指向原地址,那个地址存什么东西可就没谱了。

但如果换一种思路,我们存一个索引:

class Foo {};
Foo* foo_pool;
class Bar
{
    int member_i;
};

在调用GPU之前,把foo_pool的内容整个传过去;在GPU端通过数组索引获得Foo对象,就没有什么问题了。

但现在出现了新的问题:直接使用一个列表的pool是不方便的。我们应当把它构建成一个内存池类型,设立一系列的机制来自动管理对分配的请求。基本的想法是这样的:用两个映射结构,分别记录空余和已分配的内存块。分配的时候从一块足够大的空余内存中掐一块出来,如果没有足够大的块,就扩充pool的尺寸。回收的时候看看所回收的块是否和已有的空块相邻,如果相邻,就融合成一个大的空块。

// 用C++标准库
;