背景介绍
最近在了解性能优化相关的知识,了解到内存分配是一个可优化性能的方向,在相关书籍中看到一个固定大小的内存分配器实现,觉得挺有意思的,这里跟大家分享, 据说比通用的内存分配malloc()性能有不少提升。
源码实现
这里的代码是根据《c性能优化指南》中第13章编写的,详细的代码解析在书中有,这里就不赘述了,大家感兴趣可以瞅一瞅原文内容。
#include <iostream>
#include <algorithm>
/*memory allocator*/
struct fixed_arena_controller
{
template<int N>
fixed_arena_controller(char(&a)[N]);
fixed_arena_controller(fixed_arena_controller&) = delete;
~fixed_arena_controller() = default;
void operator=(fixed_arena_controller&) = delete;
void* allocate(size_t);
size_t block_size() const;
size_t capacity() const;
bool empty() const;
void clear();
private:
void* arena_;
size_t arena_size_;
size_t block_size_;
};
template<int N>
inline fixed_arena_controller::fixed_arena_controller(char(&a)[N]) :
arena_(a), arena_size_(N), block_size_(0) {}
inline void* fixed_arena_controller::allocate(size_t size)
{
if (!empty()) {
return nullptr;
}
block_size_ = std::max(size, sizeof(void*));
size_t count = capacity();
if (count == 0) {
return nullptr;
}
char* p;
for (p = (char*)arena_; count > 1; --count, p += size) {
*reinterpret_cast<char**>(p) = p + size;
}
*reinterpret_cast<char**>(p) = nullptr;
return arena_;
}
inline size_t fixed_arena_controller::block_size() const
{
return block_size_;
}
inline size_t fixed_arena_controller::capacity() const
{
return block_size_ ? (arena_size_ / block_size_) : 0;
}
inline void fixed_arena_controller::clear()
{
block_size_ = 0;
}
inline bool fixed_arena_controller::empty() const
{
return block_size_ == 0;
}
/*memory manager*/
template<class Arena>
struct fixed_block_memory_manager
{
template<int N>
fixed_block_memory_manager(char(&a)[N]);
fixed_block_memory_manager(fixed_block_memory_manager&) = delete;
~fixed_block_memory_manager() = default;
void operator=(fixed_block_memory_manager&) = delete;
void* allocate(size_t);
size_t block_size() const;
size_t capacity() const;
void clear();
void deallocate(void*);
bool empty() const;
private:
struct free_block
{
free_block* next;
};
free_block* free_ptr_;
size_t block_size_;
Arena arena_;
};
template<class Arena>
template<int N>
inline fixed_block_memory_manager<Arena>
::fixed_block_memory_manager(char(&a)[N]) :
arena_(a), free_ptr_(nullptr), block_size_(0)
{}
template<class Arena>
inline void* fixed_block_memory_manager<Arena>
::allocate(size_t size)
{
if (empty()) {
free_ptr_ = reinterpret_cast<free_block*>
(arena_.allocate(size));
block_size_ = size;
if (empty()) {
throw std::bad_alloc();
}
}
if (size != block_size_) {
throw std::bad_alloc();
}
auto p = free_ptr_;
free_ptr_ = free_ptr_->next;
return p;
}
template<class Arena>
inline void fixed_block_memory_manager<Arena>
::deallocate(void* p)
{
if (p == nullptr) {
return;
}
auto fp = reinterpret_cast<free_block*>(p);
fp->next = free_ptr_;
free_ptr_ = fp;
}
template<class Arena>
inline size_t fixed_block_memory_manager<Arena>
::capacity() const
{
return arena_.capacity();
}
template<class Arena>
inline void fixed_block_memory_manager<Arena>
::clear()
{
free_ptr_ = nullptr;
arena_.clear();
}
template<class Arena>
inline bool fixed_block_memory_manager<Arena>
::empty() const
{
return arena_.empty();
}
/*operator new() for class*/
class MemMgrTester
{
private:
int contents_;
public:
static fixed_block_memory_manager<fixed_arena_controller> mgr_;
MemMgrTester(int c) : contents_(c) {}
static void* operator new(size_t s)
{
std::cout << "new..." << std::endl;
return mgr_.allocate(s);
}
static void operator delete(void* p)
{
std::cout << "delete..." << std::endl;
mgr_.deallocate(p);
}
};
char arena[4004];
fixed_block_memory_manager<fixed_arena_controller> MemMgrTester::mgr_(arena);
int main()
{
MemMgrTester* pObj = new MemMgrTester(100);
delete pObj;
system("pause");
return 0;
}
参考书籍
《C性能优化指南》