C++实现多线程全局内存池(性能优化)

来源:互联网 发布:php ios aes加密解密 编辑:程序博客网 时间:2024/04/30 13:18
 #include <Windows.h>#include <iostream>#include <map>#include <string>#include <assert.h>#include <list>#include <map>#include <set>#include <vector>#include <time.h>typedef int s32;typedef unsigned int u32;typedef char c8;typedef long long s64;typedef unsigned long long u64;typedef void* LPVOID;typedef unsigned char* LPBYTE;class LockObject{public:LockObject(){InitializeCriticalSection(&mLock);}~LockObject(){DeleteCriticalSection(&mLock);}void Lock(){EnterCriticalSection(&mLock);}void UnLock(){LeaveCriticalSection(&mLock);}bool TryLock(){return TryEnterCriticalSection(&mLock);}private:LockObject(const LockObject &other){}LockObject& operator = (const LockObject &other){}private:CRITICAL_SECTION mLock;};class ScopeLock{public:ScopeLock(CRITICAL_SECTION &lock):mlock(lock){EnterCriticalSection(&mlock);}ScopeLock(LockObject &lock):mlock( reinterpret_cast<CRITICAL_SECTION&>(lock) ){EnterCriticalSection(&mlock);}~ScopeLock(){LeaveCriticalSection(&mlock);}private:ScopeLock( const ScopeLock &other):mlock(other.mlock){}ScopeLock& operator = (const ScopeLock &other){}private:CRITICAL_SECTION &mlock;};typedef struct MemoryChunk{u64 mID;LPVOID mpData;u64 mDataSize;u64 mUsedSize;MemoryChunk *mpNext;}* MemoryChunkPtr;class MemoryPool{public:MemoryPool( u64 InitMemoryBlockBytes, u64 MinMemoryBlockBytes, u64 MemoryChunkBytes ):mMemoryChunkBytes( MemoryChunkBytes ),mMinMemoryBlockBytes( MinMemoryBlockBytes ){mChunkIDPool =mTotalMemoryPoolBytes =mUsedMemoryBytes =mFreeMemoryBytes = 0;mpBeginChunk =mpNearFreeChunk =mpEndChunk = nullptr;assert( InitMemoryBlockBytes >= MinMemoryBlockBytes );_AllocateMemory( __max( InitMemoryBlockBytes, MinMemoryBlockBytes ) );}~MemoryPool(){_Destory();}template< typename T >T* GetMemory( u32 Count ){if( Count <= 0 ){assert(false);return nullptr;}const auto p = static_cast< T* >( GetMemory( Count * sizeof( T ) ) );if( nullptr == p ){assert( false );return nullptr;}for( auto i = 0; i < Count; ++i ){new ( p + i )T();}return p;}LPVOID GetMemory( u64 Bytes ){if( Bytes <= 0 ){assert( false );return nullptr;}const auto AdjustMemoryBlockBytes = _AdjustMemoryBlockBytes( Bytes );AllocChunk Chunk = { nullptr, nullptr, Bytes };ScopeLock LockBody( mLock );if( false == _FindAllocateChunk( AdjustMemoryBlockBytes, Bytes, Chunk ) ){if( false == _AllocateMemory( __max( mMinMemoryBlockBytes, AdjustMemoryBlockBytes ) ) ){assert(false);return nullptr;}if( false == _FindAllocateChunk( AdjustMemoryBlockBytes, Bytes, Chunk ) ){assert(false);return nullptr;}}mUsedMemoryBytes += AdjustMemoryBlockBytes;mFreeMemoryBytes = mTotalMemoryPoolBytes - mUsedMemoryBytes;if( mpNearFreeChunk == Chunk.mpBeginChunk ){mpNearFreeChunk = Chunk.mpEndChunk;}mAllocBlocks.insert( std::make_pair( Chunk.mpBeginChunk->mpData, Chunk ) );return Chunk.mpBeginChunk->mpData;}template<typename T>void ReleaseMemory( T* p ){if( nullptr == p ){assert( false );return;}ScopeLock LockBody( mLock );const auto Search = mAllocBlocks.find( p );if( Search == mAllocBlocks.end() ){assert( false );return;}AllocChunk &Chunk = Search->second;const auto Count = reinterpret_cast< T* >( reinterpret_cast< LPBYTE >( p ) + Chunk.mOriginalDataBytes ) - p;for(auto i = 0; i < Count; ++i){( p + i )->~T();}if( mpNearFreeChunk->mID > Chunk.mpBeginChunk->mID ){mpNearFreeChunk = Chunk.mpBeginChunk;}do{Chunk.mpBeginChunk->mUsedSize = 0;Chunk.mpBeginChunk = Chunk.mpBeginChunk->mpNext;}while( Chunk.mpBeginChunk != Chunk.mpEndChunk );mAllocBlocks.erase( p );}void ReleaseMemory( LPVOID p ){if( nullptr == p ){assert( false );return;}ScopeLock LockBody( mLock );const auto Search = mAllocBlocks.find( p );if( Search == mAllocBlocks.end() ){assert( false );return;}AllocChunk &Chunk = Search->second;if( mpNearFreeChunk->mID > Chunk.mpBeginChunk->mID ){mpNearFreeChunk = Chunk.mpBeginChunk;}do{Chunk.mpBeginChunk->mUsedSize = 0;Chunk.mpBeginChunk = Chunk.mpBeginChunk->mpNext;}while( Chunk.mpBeginChunk != Chunk.mpEndChunk );mAllocBlocks.erase(p);}private:MemoryPool():mMemoryChunkBytes( 0 ),mMinMemoryBlockBytes( 0 ){}MemoryPool( const MemoryPool &other ):mMemoryChunkBytes( 0 ),mMinMemoryBlockBytes( 0 ){}MemoryPool& operator = (const MemoryPool &other){}bool _AllocateMemory(u64 MemoryBlockSize){const auto NewMemoryBlockSize = _AdjustMemoryBlockBytes( MemoryBlockSize );auto pNewMemoryBlock = static_cast< LPBYTE >( malloc( NewMemoryBlockSize ) );if( nullptr == pNewMemoryBlock ){assert(false);return false;}const auto NewChunkCount = NewMemoryBlockSize / mMemoryChunkBytes;auto pNewMemoryChunk = static_cast< MemoryChunkPtr >( malloc( NewChunkCount * sizeof( MemoryChunk ) ) );if( nullptr == pNewMemoryChunk ){assert(false);return false;}mTotalMemoryPoolBytes += NewMemoryBlockSize;if( false == _CreateNewChunkLink( pNewMemoryBlock, pNewMemoryChunk, NewChunkCount ) ){assert(false);return false;}return true;}u64 _AdjustMemoryBlockBytes( u64 MemoryBlockSize ){const auto Mod = MemoryBlockSize % mMemoryChunkBytes;return Mod <= 0 ? MemoryBlockSize : MemoryBlockSize + mMemoryChunkBytes - Mod;}bool _CreateNewChunkLink( LPBYTE pNewMemoryBlock, MemoryChunkPtr pNewMemoryChunk, u64 NewChunkCount ){if( nullptr == mpBeginChunk ){mpBeginChunk =mpNearFreeChunk =mpEndChunk = pNewMemoryChunk;mpEndChunk->mID = ++mChunkIDPool;mpEndChunk->mpData = pNewMemoryBlock;mpEndChunk->mDataSize = mTotalMemoryPoolBytes;mpEndChunk->mUsedSize = 0;}u64 MemoryOffset = 0;for( auto i = 1; i < NewChunkCount; ++i ){mpEndChunk->mpNext = pNewMemoryChunk + i;mpEndChunk = mpEndChunk->mpNext;MemoryOffset = i * mMemoryChunkBytes;mpEndChunk->mID = ++mChunkIDPool;mpEndChunk->mpData = pNewMemoryBlock + MemoryOffset;mpEndChunk->mDataSize = mTotalMemoryPoolBytes - MemoryOffset;mpEndChunk->mUsedSize = 0;}mpEndChunk->mpNext = nullptr;HeadAddress Address = { pNewMemoryChunk, pNewMemoryBlock };mHeadAddresses.push_back( Address );return true;}struct AllocChunk;bool _FindAllocateChunk( u64 MemoryBlockSize, u64 OriginalSize, AllocChunk &Chunk ){auto pTemp = mpNearFreeChunk;while( pTemp != nullptr && ( pTemp->mDataSize < MemoryBlockSize || pTemp->mUsedSize > 0 ) ){pTemp = pTemp->mpNext;}if( nullptr == pTemp ){return false;}Chunk.mpBeginChunk = pTemp;//u64 Counter = 0;for( Chunk.mpEndChunk = Chunk.mpBeginChunk; nullptr != Chunk.mpEndChunk && Counter < OriginalSize; Chunk.mpEndChunk = Chunk.mpEndChunk->mpNext ){Counter += mMemoryChunkBytes;if( Counter > OriginalSize ){Chunk.mpEndChunk->mUsedSize = Counter - OriginalSize;}else{Chunk.mpEndChunk->mUsedSize = mMemoryChunkBytes;}}return true;}void _Destory(){for( auto i = mHeadAddresses.begin(); i != mHeadAddresses.end(); ++i ){free( i->m1);free( i->m2 );}mHeadAddresses.clear();mAllocBlocks.clear();}private:MemoryChunkPtr mpBeginChunk;MemoryChunkPtr mpNearFreeChunk;MemoryChunkPtr mpEndChunk;u64 mChunkIDPool;u64 mTotalMemoryPoolBytes;u64 mUsedMemoryBytes;u64 mFreeMemoryBytes;const u64 mMemoryChunkBytes;const u64 mMinMemoryBlockBytes;struct HeadAddress{LPVOID m1;LPVOID m2;};std::vector< HeadAddress > mHeadAddresses;struct AllocChunk{MemoryChunkPtr mpBeginChunk;MemoryChunkPtr mpEndChunk;u64 mOriginalDataBytes;};std::map<LPVOID, AllocChunk> mAllocBlocks;LockObject mLock;};


结构和上一个版本类似,所以就没写注释啦

0 0
原创粉丝点击