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
- C++实现多线程全局内存池(性能优化)
- C++实现多线程全局内存池
- C++:重载全局new/delete实现跨平台多线程内存检测
- 全局内存性能测试
- 内存池的设计和实现 -- 《C++应用程序性能优化》
- 内存池的设计和实现 -- 《C++应用程序性能优化》
- 内存池的设计和实现 -- 《C++应用程序性能优化》
- 多线程内存池实现
- 多线程内存池实现
- 内存池性能优化 固定内存块使用 之 链表实现
- 性能优化,多线程
- 性能优化:多线程
- [转]C++ 应用程序性能优化----内存池
- C++ 应用程序性能优化 -- 内存池
- C++ 应用程序性能优化---内存池技术
- C++ 应用程序性能优化 -- 内存池
- C++ 应用程序性能优化:内存池
- Android 性能、内存优化
- 说说Android的广播(5) - 广播的历史
- Android Studio使用指南
- [bzoj2339][HNOI2011]卡农
- Xpath与lxml_2XPath语法
- 如何获取匿名内部类的数据
- C++实现多线程全局内存池(性能优化)
- java—异常处理机制
- Axure教程网
- UILabel 高度的自适应与获取
- SendInput模拟键盘操作
- Axure教程 axure新手入门基础(1)
- Code Craft 2016初赛的一点体会
- 排序算法——直接插入法排序
- VSLAM学习之(一)