64,635
社区成员
发帖
与我相关
我的任务
分享
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
#ifndef __MEMPOOL_H__
#define __MEMPOOL_H__
#include <assert.h>
using namespace std;
enum MemType
{
Mem_0_Bit_Size = 0,
Mem_16_Bit_Size = 16,
Mem_32_Bit_Size = 32,
Mem_64_Bit_Size = 64,
Mem_128_Bit_Size = 128,
Mem_256_Bit_Size = 256,
Mem_512_Bit_Size = 512,
Mem_1k_Bit_Size = 1024,
Mem_2k_Bit_Size = 2*1024,
Mem_4k_Bit_Size = 4*1024,
Mem_8k_Bit_Size = 8*1024,
Mem_16k_Bit_Size = 16*1024,
Mem_32k_Bit_Size = 32*1024,
Mem_64k_Bit_Size = 64*1024,
Mem_128k_Bit_Size = 128*1024,
Mem_256k_Bit_Size = 256*1024,
Mem_512k_Bit_Size = 512*1024,
Mem_1m_Bit_Size = 1024*1024,
};
struct MemBlock
{
MemBlock(int nMenLen) : m_nMemLen(nMenLen),m_pPreBlock(NULL),m_pNextBlock(NULL){}
int m_nMemLen;
MemBlock* m_pPreBlock;
MemBlock* m_pNextBlock;
};
class MemTypeAllocator
{
public:
MemTypeAllocator(int nBlockType);
~MemTypeAllocator();
void* AllocMemory();
void FreeMemory(void* pFreeMemory);
int GetTotalBlockCount();
int GetFreeBlockCount();
int GetBlockType();
void DumpNode();
private:
static const int BlockMax = 20;
int m_nBlockType;
long m_nTotalBlockNum;
long m_nFreeBlockNum;
MemBlock* m_pBeginBlock;
MemBlock* m_pEndBlock;
};
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
MemTypeAllocator::MemTypeAllocator(int nBlockType) : m_nBlockType(nBlockType),m_nTotalBlockNum(0),m_nFreeBlockNum(0),m_pBeginBlock(NULL),m_pEndBlock(NULL)
{
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
MemTypeAllocator::~MemTypeAllocator()
{
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
void* MemTypeAllocator::AllocMemory()
{
void* pRet = NULL;
if (m_pEndBlock != NULL)
{
assert(m_pEndBlock->m_pNextBlock == NULL);
MemBlock* pTond = m_pEndBlock;
pRet = (char*)m_pEndBlock + sizeof(MemBlock);
m_pEndBlock = m_pEndBlock->m_pPreBlock;
if (m_pEndBlock != NULL)
{
m_pEndBlock->m_pNextBlock = pTond->m_pNextBlock;
}
else
{
m_pBeginBlock = NULL;
}
pTond->m_pPreBlock = NULL;
m_nFreeBlockNum--;
}
else
{
void* pMemory = malloc(m_nBlockType + sizeof(MemBlock));
MemBlock* pNewBlock = (MemBlock*)pMemory;
assert(pNewBlock != NULL);
pNewBlock->m_nMemLen = m_nBlockType;
pNewBlock->m_pNextBlock = NULL;
pNewBlock->m_pPreBlock = NULL;
pRet = (char*)pNewBlock + sizeof(MemBlock);
m_nTotalBlockNum++;
}
return pRet;
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
void MemTypeAllocator::FreeMemory(void* pFreeMemory)
{
assert(pFreeMemory != NULL);
if (pFreeMemory == NULL)
{
return;
}
MemBlock* pMemBlock = (MemBlock*)((char*)pFreeMemory - sizeof(MemBlock));
if (m_nFreeBlockNum > BlockMax)
{
free(pMemBlock);
pMemBlock = NULL;
m_nTotalBlockNum--;
}
else
{
if (NULL == m_pBeginBlock)
{
m_pBeginBlock = pMemBlock;
m_pEndBlock = pMemBlock;
}
else
{
pMemBlock->m_pNextBlock = m_pBeginBlock;
m_pBeginBlock->m_pPreBlock = pMemBlock;
m_pBeginBlock = pMemBlock;
}
m_nFreeBlockNum++;
}
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
int MemTypeAllocator::GetTotalBlockCount()
{
return m_nTotalBlockNum;
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
int MemTypeAllocator::GetFreeBlockCount()
{
return m_nFreeBlockNum;
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
int MemTypeAllocator::GetBlockType()
{
return m_nBlockType;
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
void MemTypeAllocator::DumpNode()
{
MemBlock* pTond = m_pBeginBlock;
while (pTond)
{
TRACE("Node:%p->",pTond);
pTond = pTond->m_pNextBlock;
}
TRACE("NULL\n");
TRACE("pBegin : %p pEnd:%p\n",m_pBeginBlock,m_pEndBlock);
}
#endif
struct MyStruct
{
char tt[128];
};
const int arrsize = 30;
const int looptime = 100000;
CMemoryPool<MyStruct>test;
MemoryPool mempool;
mempool.InitMemoryPool();
clock_t beg, end;
char buf[64];
int ncount = 0;
MyStruct * arr[arrsize] = { 0, };
test.Init(100, 100);
beg = clock();
for (int i = 0; i < looptime;i++)
{
for (int j = 0;j < arrsize;j++)
{
arr[j] = test.Alloc();
if (NULL == arr[j])
ncount++;
}
for (int j = 0;j < arrsize;j++)
{
test.Free(arr[j]);
}
}
end = clock();
sprintf_s(buf, "used time %f s alloc createbandtimes:%d\n", 1.0*(end - beg) / CLOCKS_PER_SEC,test.GetCreateBandTimes());
OutputDebugString(buf);
beg = clock();
for (int i = 0; i < looptime;i++)
{
for (int j = 0;j < arrsize;j++)
{
//arr[j] = new MyStruct;
arr[j] = (MyStruct*)malloc(sizeof(MyStruct));
}
for (int j = 0;j < arrsize;j++)
{
//delete arr[j];
free(arr[j]);
}
}
end = clock();
sprintf_s(buf, "used time %f s\n", 1.0*(end - beg) / CLOCKS_PER_SEC);
OutputDebugString(buf);
beg = clock();
for (int i = 0; i < looptime;i++)
{
for (int j = 0;j < arrsize;j++)
{
arr[j] = (MyStruct*)mempool.Malloc(sizeof(MyStruct));
}
for (int j = 0;j < arrsize;j++)
{
mempool.Free(arr[j]);
}
}
end = clock();
sprintf_s(buf, "used time %f s\n", 1.0*(end - beg) / CLOCKS_PER_SEC);
OutputDebugString(buf);
unsigned int WINAPI WorkThread(void* pParam)
{
int nRet = -1;
MemoryPool* pMemoryPool = (MemoryPool*)pParam;
int nNum = 10000;
int nSize = 1000;
int nBeginTick = GetTickCount();
int nEndTick = 0;
void* pRet[100];
char* ptrArry = NULL;
//10W 1435 7675 203 796
for (int i = 0;i < nNum;i++)
{
/*
ptrArry = (char*)malloc(nSize);
free(ptrArry);
*/
/*
ptrArry = (char*)pMemoryPool->Malloc(nSize);
pMemoryPool->Free(ptrArry);
*/
/*
for (int j = 0; j < 30;j++)
{
pRet[j] = malloc(nSize);
}
for (int j = 0; j < 30;j++)
{
free(pRet[j]);
}
*/
for (int j = 0; j < 30;j++)
{
pRet[j] = pMemoryPool->Malloc(nSize);
}
for (int j = 0; j < 30;j++)
{
pMemoryPool->Free(pRet[j]);
}
//mempool.DunmMemoryPool();
}
nEndTick = GetTickCount() - nBeginTick;
TRACE("UserTime : %d\n",nEndTick);
//pMemoryPool->DunmMemoryPool();
return nRet;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
HMODULE hModule = ::GetModuleHandle(NULL);
if (hModule != NULL)
{
// initialize MFC and print and error on failure
if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
// TODO: code your application's behavior here.
}
}
else
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: GetModuleHandle failed\n"));
nRetCode = 1;
}
MemoryPool mempool;
mempool.InitMemoryPool();
unsigned int dwThreadID = 0;
for (int n = 0;n < 4;n++)
{
_beginthreadex(NULL,0,WorkThread,&mempool,0,&dwThreadID);
}
while(1)
{
}
return nRetCode;
}
class MemoryPool
{
public:
MemoryPool(){};
~MemoryPool(){};
void InitMemoryPool();
void UnInitMemoryPool();
void* Malloc(int nSize);
void Free(void* pMemory);
long GetTotalMemorySize();
long GetFreeMemorySize();
int GetTotalBlockCountForType(int nType);
int GetFreeBlockCountForType(int nType);
int GetBlockTypeCount();
void DunmMemoryPool();
protected:
int FitSize(int nSize);
int FindElement(int nType);
int FindType(int nElement);
private:
static const int MemTypeMax = 17;
MemTypeAllocator* m_arrayAllocator[MemTypeMax];
CRITICAL_SECTION m_cs;
};
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
int MemoryPool::FindElement(int nType)
{
int nRet = -1;
if (nType > 0 && nType <= Mem_1m_Bit_Size)
{
nRet = (int)(log10(nType*1.0)/log10(2.0) - 4);
}
return nRet;
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
int MemoryPool::FindType(int nElement)
{
int nRet = -1;
if (nElement >= 0 && nElement < MemTypeMax)
{
nRet = (int)pow(2.0,nElement + 4);
}
return nRet;
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
void MemoryPool::InitMemoryPool()
{
InitializeCriticalSection(&m_cs);
for (int i = 0;i < MemTypeMax;i++)
{
int nType = FindType(i);
m_arrayAllocator[i] = new MemTypeAllocator(nType);
}
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
void MemoryPool::UnInitMemoryPool()
{
DeleteCriticalSection(&m_cs);
for (int i = 0;i < MemTypeMax;i++)
{
delete m_arrayAllocator[i];
m_arrayAllocator[i] = NULL;
}
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
int MemoryPool::FitSize(int nSize)
{
int nRet = -1;
if (nSize <= 0)
{
return nRet;
}
else if (nSize >0 && nSize <= Mem_16_Bit_Size)
{
nRet = Mem_16_Bit_Size;
}
else if (nSize <= Mem_32_Bit_Size)
{
nRet = Mem_32_Bit_Size;
}
else if (nSize <= Mem_64_Bit_Size)
{
nRet = Mem_64_Bit_Size;
}
else if (nSize <= Mem_128_Bit_Size)
{
nRet = Mem_128_Bit_Size;
}
else if (nSize <= Mem_256_Bit_Size)
{
nRet = Mem_256_Bit_Size;
}
else if (nSize <= Mem_512_Bit_Size)
{
nRet = Mem_512_Bit_Size;
}
else if (nSize <= Mem_1k_Bit_Size)
{
nRet = Mem_1k_Bit_Size;
}
else if (nSize <= Mem_2k_Bit_Size)
{
nRet = Mem_2k_Bit_Size;
}
else if (nSize <= Mem_4k_Bit_Size)
{
nRet = Mem_4k_Bit_Size;
}
else if (nSize <= Mem_8k_Bit_Size)
{
nRet = Mem_8k_Bit_Size;
}
else if (nSize <= Mem_16k_Bit_Size)
{
nRet = Mem_16k_Bit_Size;
}
else if (nSize <= Mem_32k_Bit_Size)
{
nRet = Mem_32k_Bit_Size;
}
else if (nSize <= Mem_64k_Bit_Size)
{
nRet = Mem_64k_Bit_Size;
}
else if (nSize <= Mem_128k_Bit_Size)
{
nRet = Mem_128k_Bit_Size;
}
else if (nSize <= Mem_256k_Bit_Size)
{
nRet = Mem_256k_Bit_Size;
}
else if (nSize <= Mem_512k_Bit_Size)
{
nRet = Mem_512k_Bit_Size;
}
else if (nSize <= Mem_1m_Bit_Size)
{
nRet = Mem_1m_Bit_Size;
}
else
{
//如果申请大于1M的内存直接申请
//....
}
return nRet;
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
void* MemoryPool::Malloc(int nSize)
{
void* pRet = NULL;
int nType = FitSize(nSize);
if (nType > 0)
{
int nElement = FindElement(nType);
if (nElement > 0)
{
EnterCriticalSection(&m_cs);
pRet = m_arrayAllocator[nElement]->AllocMemory();
LeaveCriticalSection(&m_cs);
}
else
{
assert(0);
}
}
else
{
void* pTond = malloc(nSize + sizeof(MemBlock));
assert(pTond != NULL);
*(int*)pTond = -1; //自行分配内存
pRet = (char*)pTond + sizeof(MemBlock);
}
return pRet;
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
void MemoryPool::Free(void* pMemory)
{
if (pMemory == NULL)
{
return;
}
int* pType = (int*)((char*)pMemory - sizeof(MemBlock));
assert(pType != NULL);
int nElement = FindElement(*pType);
if (nElement >= 0)
{
EnterCriticalSection(&m_cs);
m_arrayAllocator[nElement]->FreeMemory(pMemory);
LeaveCriticalSection(&m_cs);
}
else
{
void* pTond = (char*)pMemory - sizeof(MemBlock);
free(pTond);
}
return;
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
long MemoryPool::GetTotalMemorySize()
{
long lRet = -1;
for (int i = 0;i < MemTypeMax;i++)
{
lRet += m_arrayAllocator[i]->GetTotalBlockCount()*m_arrayAllocator[i]->GetBlockType();
}
return lRet;
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
long MemoryPool::GetFreeMemorySize()
{
long lRet = -1;
for (int i = 0;i < MemTypeMax;i++)
{
lRet += m_arrayAllocator[i]->GetFreeBlockCount()*m_arrayAllocator[i]->GetBlockType();
}
return lRet;
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
int MemoryPool::GetTotalBlockCountForType(int nType)
{
int nRet = -1;
int nElement = FindElement(nType);
if (nElement >= 0)
{
nRet = m_arrayAllocator[nElement]->GetTotalBlockCount();
}
return nRet;
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
int MemoryPool::GetFreeBlockCountForType(int nType)
{
int nRet = -1;
int nElement = FindElement(nType);
if (nElement >= 0)
{
nRet = m_arrayAllocator[nElement]->GetFreeBlockCount();
}
return nRet;
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
int MemoryPool::GetBlockTypeCount()
{
int nRet = -1;
nRet = MemTypeMax;
return nRet;
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
void MemoryPool::DunmMemoryPool()
{
for (int i = 0;i < MemTypeMax;i++)
{
m_arrayAllocator[i]->DumpNode();
}
}