常运用于游戏引擎的FreeList实现

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_44312858/article/details/96787788

常运用于游戏引擎的FreeList实现


最近在读的Game Engine Architecture里面讲到了Memory Management,其中小小的提到了FreeList。FreeList在游戏引擎中主要是用于灵活的,快速的对小型相同类型的Object进行内存分布和释放,比如说子弹。因为FreeList的实现相对简单,所以来分享下。

FreeList有以下几个特点:

  1. FreeList其实就是一个LinkedList,但是把LinkedList中的next存在了Value里面。
  2. FreeList只对未被分配内存的Node进行管理。
  3. 用户需要对被使用的内存进行释放。
  4. FreeList没有内存碎片化的问题。
    先来看一个基础的interface。
template<class T, std::size_t N>
class FreeList {
public:
    struct Element {
        Element* next;
    };
private:
    alignas(alignof(T)) char memoryPool_[N * sizeof(T)];
    Element* head;

public:
    FreeList();

    T* Allocate();
    void Deallocate(T*);
};

在上面这种实现方法中,next是一个pointer,所以类型T的内存需要大于指针的内存,我们把这个assert放在constructor里面,next也可以是一个index,这样的话可以将FreeList拥有更小内存的T。如果用index作为next需要注意的是如果T是1 byte,那么这个list最多可以存2^8个Element。

template<class T, std::size_t N>
FreeList<T, N>::FreeList() {
    static_assert(sizeof(T) >= sizeof(T*), "size of T is less than size of an address");
    //….
}

在constructor中,我们需要做的仅仅是对memoryPool_中的每个node的next进行负值。

//FreeList Constructor….
Element* runningNode = head;

    while(true) {
        if (reinterpret_cast<char*>(runningNode) < memoryPool_ + (N-1) * sizeof(T)){
            runningNode->next = reinterpret_cast<Element*>(reinterpret_cast<T*>(runningNode) + 1);
        }
        else {
            runningNode->next = nullptr;
            break;
        }
        runningNode = runningNode->next;
    };
//….

接下来是Allocate,在Allocate中,我们用head取出FreeList中的其中一个值,然后将head指向next,如果head是nullptr那么就直接return nullptr。

//Allocate...
Element* temp = head;
head = head->next;
return reinterpret_cast<T*>(temp);
//...
在Deallocate,我们让返回的值重新回到FreeList中。

//Deallocate...
Element* temp = head;
head = reinterpret_cast<Element*>(p);
head->next = temp;
//...

其实之前本来是想写Stack Based Allocator的,但是因为Stack Based Allocator比FreeList更难一些,限于我自己本身写作能力就暂时不发这种长篇的了。如果有同学想看Stack Based Allocator可以看从这个开始:Howard Hinnant。如果有同学对游戏引擎和游戏开发感兴趣欢迎交流。

因为才开始写技术文,也欢迎指出文章中的错误:)

最后这个FreeList在我自己的引擎的FixedArrayAllocator.hpp中变种的运用到。欢迎查看:),如果对引擎感兴趣可以查看我的twitter

展开阅读全文

没有更多推荐了,返回首页