关于Memory Pool的一些想法及实现

在《Effective C++》(Second Edition)中Item 10 "Write operator delete if you write operator new"中提到一个Memory Pool技术, 并给出一个例子
void *Airplane::operator new(size_t size)
{
if(size != sizeof(Airplane))
return ::operator new(size);
Airplane *p = headOfFreeList;
if(p)
headOfFreeList = p->next;
else
{
Airplane * newBlock = static_cast<Airplane *>(::operator new(BLOCK_SIZE*sizeof(Airplane)));
}
for(int i=1; i<BLOCK_SIZE-1; ++i)
newBlock[i].next = &newBlock[i+1];
newBlock[BLOCK_SIZE-1].next = 0;
p= newBlock;
headOfFreeList = &newBlock[1];
}
书中提到, 用这种技术的好处有二: 一. 节省空间, 普通的new操作由于需要记住申请的大小, 一般需要更多的空间. 而应用这种技术则不需要额外的空间. 二. 操作速度快, 此种的new和delete操作只是对链表的添加和删除操作, 不需要做真正的系统空间分配, 速度更快.

但明显, 例子中给出的操作只能针对Airplane类进行操作, 试想, 能不能扩展到对任何类进行这样的Memory Pool操作呢?

第一想法就是用template.
花了一中午的时间写了一个CMemoryPool模板类. 如下所示

#ifndef __MEMORYPOOL_H__
#define __MEMORYPOOL_H__
#include <list>

template <class _T>
class CMemoryPool  
{
public:
CMemoryPool(size_t init_size = 100) : INIT_SIZE(init_size), m_memoryHeadList(5)
{
headOfFreeList = NULL;
}
~CMemoryPool()
{
std::list<Envelope *>::iterator iter;
for(iter = m_memoryHeadList.begin(); iter != m_memoryHeadList.end(); ++iter)
{
Envelope *block = *iter;
::operator delete(block);
}
}
_T *alloc()
{
Envelope *p = headOfFreeList;
if(p)
headOfFreeList = p->next;
else
{
const size_t ObjectSize = (sizeof(_T) > sizeof(Envelope)) ? sizeof(_T) : sizeof(Envelope);
// 申请空间
Envelope *newBlock = static_cast<Envelope *>(::operator new(INIT_SIZE * ObjectSize));
// 初始化空闲空间列表
for(int i=1; i<INIT_SIZE; ++i)
((Envelope *)((char *)newBlock + i * ObjectSize))->next = (Envelope *)((char *)newBlock + (i+1) * ObjectSize);
((Envelope*)((char *)newBlock + (INIT_SIZE - 1) * ObjectSize))->next = NULL;
// 保存首址
m_memoryHeadList.push_back(newBlock);
p = newBlock;
headOfFreeList = (Envelope*)((char *)newBlock + ObjectSize);
}
return (_T *)p;
}
void free(_T *p)
{
if(p==NULL)
return;
Envelope *freeBlock = (Envelope *)p;
freeBlock->next = headOfFreeList;
headOfFreeList = freeBlock;
}
private:
union Envelope
{
_T *object;
union Envelope *next;
};
const size_t INIT_SIZE;// 默认每次分配多少初始大小的空间
Envelope *headOfFreeList; // 当前自由空间首址
std::list<Envelope *> m_memoryHeadList; // 申请空间首址向量
};
#endif // !defined __MEMORYPOOL_H__

此模板类对于内建类型, 可做如下使用.

#include <iostream>
#include "MemoryPool.h"
int main()
{
CMemoryPool<double> d_Pool;
double *p[10];
int i;
for(i=0; i<10; ++i)
{
p[i] = d_Pool.alloc();
std::cout<<p[i]<<std::endl;
}
for(i=0; i<5; ++i)
d_Pool.free(p[i]);
for(i=0; i<5; ++i)
p[i] = d_Pool.alloc();
for(i=0; i<10; ++i)
std::cout<<p[i]<<std::endl;
return 0;
}

如果仅仅这样使用, 还没有达到所要求的目的.
关键是对于自己的自定义类, 通过重载operator new与operator delete来使用Memory Pool
如下:

#include <iostream>
#include "MemoryPool.h"
class MyClass
{
public:
MyClass();
~MyClass();
static void * operator new(size_t t);
static void operator delete(void *p);
private:
static CMemoryPool<MyClass> st_objectPool;
};
CMemoryPool<MyClass> MyClass::st_objectPool(10);
MyClass::MyClass()
{
std::cout<<"A() called"<<std::endl;
}
MyClass::~MyClass()
{
std::cout<<"~A() called"<<std::endl;
}
void * MyClass::operator new(size_t t)
{
if(t != sizeof(MyClass))
return ::operator new(t);
return MyClass::st_objectPool.alloc();
}
void MyClass::operator delete(void *p)
{
MyClass::st_objectPool.free((MyClass *)p);
}

int main()
{
MyClass *ptr;
ptr = new MyClass;
delete ptr;
return 0;
}

至此, 已经完成了对于任何类的一个CMemoryPool类的写法, 自然会想到, 怎么样去写一个基类CMemoryPoolBaseClass, 让所有继承该类的子类都具有这种内存池的动态内存分配方式呢?

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Memory Compiler 实现存储器布局生成的过程通常包括以下步骤: 1. 存储器规格输入:首先,用户需要提供存储器的规格要求,包括存储容量、字长、位宽等。这些规格要求是根据设计需求和约束来确定的。 2. 布局生成算法:Memory Compiler 使用布局生成算法来根据存储器规格生成初始布局。布局生成算法通常会考虑一些因素,例如电路的可靠性、功耗、面积等。 3. 物理布局优化:生成初始布局后,Memory Compiler 会进行一系列的优化步骤来改进物理布局。这些优化步骤可以包括单元排列、单元间距、引脚位置的调整,以及电路参数的优化等。 4. 约束和规则检查:在布局生成和优化过程中,Memory Compiler 会进行约束和规则的检查,确保生成的布局符合设计要求和限制条件。这些约束和规则可以包括电气特性、电路连通性等方面的要求。 5. 时序和功耗优化:Memory Compiler 还可以进行时序和功耗优化,以提高存储器的性能和功耗效率。通过调整电路参数和布局方式,以及使用高级优化算法,可以使存储器的访问速度更快、时序更稳定。 6. 布局结果输出:最后,Memory Compiler 会将生成的最终布局结果输出,通常以物理设计数据库(PDB)或者其他标准格式的文件形式提供给后续的电路设计和验证流程使用。 需要注意的是,不同的 Memory Compiler 可能采用不同的实现方法和算法来进行存储器布局生成,具体的实现细节可能会有所不同。但总体来说,这些步骤可以帮助理解 Memory Compiler 是如何实现存储器布局生成的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值