MNN/source/core/BufferAllocator.hpp

122 lines
3.5 KiB
C++
Raw Normal View History

2019-04-17 10:49:11 +08:00
//
// BufferAllocator.hpp
// MNN
//
// Created by MNN on 2018/08/20.
// Copyright © 2018, Alibaba Group Holding Limited
//
#ifndef BufferAllocator_hpp
#define BufferAllocator_hpp
#include <map>
#include <memory>
#include <vector>
#include "MNNMemoryUtils.h"
#include "NonCopyable.hpp"
2021-04-08 15:34:23 +08:00
#include "AutoStorage.h"
2019-04-17 10:49:11 +08:00
namespace MNN {
/** memory utils wrapper. provides memory reusing with alignment ability. */
2019-12-27 22:16:57 +08:00
class MNN_PUBLIC BufferAllocator : public NonCopyable {
2019-04-17 10:49:11 +08:00
public:
2020-12-15 14:12:35 +08:00
class Allocator {
public:
Allocator() = default;
virtual ~ Allocator() = default;
2022-02-18 11:30:27 +08:00
virtual std::pair<void*, size_t> onAlloc(size_t size, size_t align) = 0;
virtual void onRelease(std::pair<void*, size_t> ptr) = 0;
2020-12-15 14:12:35 +08:00
static std::shared_ptr<Allocator> createDefault();
static std::shared_ptr<Allocator> createRecurse(BufferAllocator* parent);
};
2019-04-17 10:49:11 +08:00
/**
* @brief init buffer allocator with pointer alignment.
* @param align given pointer alignment.
*/
2022-02-18 11:30:27 +08:00
BufferAllocator(std::shared_ptr<Allocator> parent, size_t align = MNN_MEMORY_ALIGN_DEFAULT) : mAllocator(parent), mAlign(align) {
2019-04-17 10:49:11 +08:00
// nothing to do
}
/**
* @brief deinit buffer allocator. frees all allocated memories.
*/
~BufferAllocator() {
release();
}
public:
/**
* @brief alloc CHUNK pointer with given size. if any reusable pointer matches size, reuse it.
* @param size given size.
* @param seperate if true, the memory can't be alloc from free pool
* @return allocated or used CHUNK pointer.
* @sa free
* @sa release
*/
2022-02-18 11:30:27 +08:00
std::pair<void*, size_t> alloc(size_t size, bool seperate = false, size_t align = 0);
2019-04-17 10:49:11 +08:00
/**
* @brief mark CHUNK pointer as reusable.
* @param pointer given CHUNK pointer.
* @return true if pointer is a CHUNK pointer, false otherwise.
* @sa release
*/
2022-02-18 11:30:27 +08:00
bool free(std::pair<void*, size_t> pointer);
2019-04-17 10:49:11 +08:00
/**
* @brief free all allocated memories.
* @sa allocSeparate
* @sa alloc
* if allRelease, clear all memory , otherwise delete freelist
2019-04-17 10:49:11 +08:00
*/
void release(bool allRelease = true);
2019-04-17 10:49:11 +08:00
/**
* @brief query total size allocated indeed.
* @return total size allocated indeed.
*/
size_t totalSize() const {
return mTotalSize;
}
/*
For multi thread case,
we must assume that the memory use by different thread don't conflict
begin barrier / end barrier means enter the alloc for multi-thread
begin group / end group means the memory allocated belong to one thread
different group must use different memory,
but the origin freelist can be used by every group
*/
void barrierBegin();
void barrierEnd();
void beginGroup();
void endGroup();
private:
2021-04-08 15:34:23 +08:00
class Node : public RefCount {
2019-04-17 10:49:11 +08:00
public:
~Node();
2022-02-18 11:30:27 +08:00
std::pair<void*, size_t> pointer;
2021-04-08 15:34:23 +08:00
SharedPtr<Node> parent = nullptr;
2022-02-18 11:30:27 +08:00
size_t size;
size_t useCount = 0;
2020-12-15 14:12:35 +08:00
Allocator* outside = nullptr;
2019-04-17 10:49:11 +08:00
};
2021-04-08 15:34:23 +08:00
typedef std::multimap<size_t, SharedPtr<Node>> FREELIST;
2019-04-17 10:49:11 +08:00
2021-04-08 15:34:23 +08:00
static void returnMemory(FREELIST* list, SharedPtr<Node> node, bool permitMerge = true);
2022-02-18 11:30:27 +08:00
std::pair<void*, size_t> getFromFreeList(FREELIST* list, size_t size, bool permiteSplit, size_t align);
2019-04-17 10:49:11 +08:00
2022-02-18 11:30:27 +08:00
std::map<std::pair<void*, size_t>, SharedPtr<Node>> mUsedList;
2019-04-17 10:49:11 +08:00
FREELIST mFreeList;
size_t mTotalSize = 0;
2020-10-25 11:01:04 +08:00
FREELIST* mCurrentFreeList = nullptr;
2019-04-17 10:49:11 +08:00
std::vector<std::shared_ptr<FREELIST>> mGroups;
2020-12-15 14:12:35 +08:00
std::shared_ptr<Allocator> mAllocator;
2022-02-18 11:30:27 +08:00
size_t mAlign;
2019-04-17 10:49:11 +08:00
};
} // namespace MNN
#endif