这是试验性的程序, 虽然算法实现简弱, 当在编译器优化后实验结果, 性能比用全局new delete的内存管理好了很多,我这里有考虑到多线程 看来在大量使用内存分配的程序,用内存池是能够显著提高性能的; 有时间我会改进算法,有高手看到, 请指点一二, 我是非专业的, 算法方面很弱;
还有数组的内存分配遇到了一些问题; 以下数组的内存分配的一般模式
void * operator new[](size_t size); void operator delete[](void *p, size_t size);
可惜的是new里的size和delete你的size在vc, bc下并不匹配(g++则一样, 比较好); 这是的分配数组是需要保存指针及对应的大小(一般用hash), 这要消耗不少时间;
#pragma warning(disable: 4530) #pragma warning(disable: 4786) #include <map> #include <cassert> #include <iostream> #include <algorithm> #include <exception> #include <iomanip> #include <list> using namespace std;
#include <windows.h>
template<size_t PreAllocSize = 1024> class MemoryPool { protected:
struct MemoryBlock { char *_Address; size_t _Size; MemoryBlock * _Next; MemoryBlock(void *pbegin, size_t size) : _Address((char *)pbegin), _Size(size), _Next(NULL) { }; };
struct Lock { CRITICAL_SECTION &CS; Lock(CRITICAL_SECTION &cs) : CS(cs) { EnterCriticalSection(&CS); } ~Lock() { LeaveCriticalSection(&CS); } };
char _Buffer[PreAllocSize]; char *_Begin, *_End; CRITICAL_SECTION _csLock; list<MemoryBlock * > _MemoryList;
void CreateList() { _MemoryList.push_back(new MemoryBlock(_Begin, PreAllocSize)); }
void FreeList() { list< MemoryPool::MemoryBlock * >::iterator iter;
for(iter = _MemoryList.begin(); iter != _MemoryList.end(); iter ++) delete (*iter);
_MemoryList.clear(); }
void *FFA_Alloc(size_t size)// First fit algorithm { char *p = NULL; list< MemoryPool::MemoryBlock * >::iterator iter;
for(iter = _MemoryList.begin(); iter != _MemoryList.end(); iter ++) { if(size < (*iter)->_Size) { p = (*iter)->_Address, (*iter)->_Address += size, (*iter)->_Size -= size; break; } else { if(size == (*iter)->_Size) { p = (*iter)->_Address; delete (*iter); _MemoryList.erase(iter); break; } } }
return p; }
bool FFA_Free(char *p, size_t size) { if(p < _Begin || p + size > _End) return false;
list< MemoryPool::MemoryBlock * >::iterator iter, temp_iter;
for(iter = _MemoryList.begin(); iter != _MemoryList.end(); iter ++) { if(p < (*iter)->_Address) //find the insert point { if(p + size > (*iter)->_Address)//error return false;
if(iter == _MemoryList.begin()) { if(p + size == (*iter)->_Address) //union next_node (*iter)->_Address = p, (*iter)->_Size += size; else //insert _MemoryList.insert(iter, new MemoryBlock(p, size)); } else { temp_iter = iter, temp_iter--; //get pre_node
if((*temp_iter)->_Size + (*temp_iter)->_Address == p) //must union pre_node { if(p + size == (*iter)->_Address)//union next_node and pre_node { (*temp_iter)->_Size += size + (*iter)->_Size ; _MemoryList.erase(iter); } else //just union pre_node (*temp_iter)->_Size += size; } else { if(p + size == (*iter)->_Address)//union next_node (*iter)->_Size += size, (*iter)->_Address = p; else _MemoryList.insert(iter, new MemoryBlock(p, size)); } } return true; }// if(p < (*iter)->_Begin) } //for
if(_MemoryList.size() == 0) // null list _MemoryList.insert(_MemoryList.end(), new MemoryBlock(p, size)); else //push back of list { list< MemoryPool::MemoryBlock * >::reverse_iterator r_iter = _MemoryList.rbegin();
if((*r_iter)->_Size + (*r_iter)->_Address == p) //must union pre_node (*r_iter)->_Size += size; else _MemoryList.insert(_MemoryList.end(), new MemoryBlock(p, size)); }
return true; }
void *BFA_Alloc(size_t size)// Best fit algorithm { }
bool BFA_Free(char *p, size_t size) { }
void *WFA_Alloc(size_t size)// Worst fit algorithm { }
bool WFA_Free(char *p, size_t size) { }
public:
MemoryPool()// : _MemoryHash(PreAllocSize / 16) { _Begin = _Buffer, _End = _Buffer + PreAllocSize; InitializeCriticalSection(&_csLock); CreateList(); }
~MemoryPool() { DeleteCriticalSection(&_csLock); FreeList(); }
void *Alloc(size_t size) { Lock lock(_csLock);
void *p = FFA_Alloc(size);
return p ? p : malloc(size); }
void Free(void *address, int size) { Lock lock(_csLock);
if(!size) size = 1;
if(!FFA_Free((char *)address, size)) { printf("\nfree error : address %p size %d\n", address, size); free(address); } }
void PrintList() { printf("\n"); int i;
if(_MemoryList.size() == 0) { printf("no memory!\n"); return; }
list< MemoryPool::MemoryBlock * >::iterator iter; for(i = 0, iter = _MemoryList.begin(); iter != _MemoryList.end(); iter ++, i ++) printf("%d : Address %p offset %d, size %d;\n", i, (*iter)->_Address, (*iter)->_Address - _Begin, (*iter)->_Size); } };
class Object { public:
static MemoryPool<2 * 1024 * 1024> _MP;
void * operator new (size_t size) { return _MP.Alloc(size); }; void operator delete(void * p, size_t size) { _MP.Free(p, size); }; };
MemoryPool<2 * 1024 * 1024> Object::_MP;
int main(int argc, char* argv[]) { int i; Object **x = new Object *[1000000];
int bt = GetTickCount();
for(i = 0 ; i < 1000000; i++) x[i] = new Object();
for( i = 0 ; i < 1000000; i++) delete x[i]; cout << "使用内存池 " << GetTickCount() - bt << endl;
bt = GetTickCount();
for(i = 0 ; i < 1000000; i++) x[i] = ::new Object[10];
for( i = 0 ; i < 1000000; i++) ::delete x[i]; cout << "使用全局NEW " << GetTickCount() - bt << endl;
return 0; }

|