C++实现多线程全局内存池(性能优化)
C++实现多线程全局内存池(性能优化)
http://blog.csdn.net/f_r_e_e_x/article/details/51615329
- #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;
- };
结构和上一个版本类似,所以就没写注释啦

浙公网安备 33010602011771号