• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 87  文章 - 279  trackbacks - 0
            <2010年11月>
            31123456
            78910111213
            14151617181920
            21222324252627
            2829301234
            567891011

            潛心看書研究!

            常用鏈接

            留言簿(19)

            隨筆分類(81)

            文章分類(89)

            相冊

            ACM OJ

            My friends

            搜索

            •  

            積分與排名

            • 積分 - 217802
            • 排名 - 117

            最新評論

            閱讀排行榜

            評論排行榜

            用了《Modern C++ Design》上的那個Chunk,在Chunk查找Block的時間是O(1),但是在MemPool的ChunkList里面查找某內存地址卻需要O(n)的時間復雜度,因為我的算法只是線性的便利ChunkLisk的鏈表,所以但內存池里面同時存在大量小對象時候,效果不是很好,比普通的new還差,但是如果內存池內同時存在的小對象的數目較小的時候,可以獲得不錯的性能,計劃version2.0要改進算法,但是嘗試加Map做O(logn)的查找,效果很不好,常數太大了,如果加hash又耗太多內存,暫時沒什么想法,估計要改數據結構了,+個freelist可以實現new操作O(1)但是free操作很難搞,怎樣快速定位某個內存屬于哪個Chunk呢?有點難度,再看看書,再想想。

            Chunk.h

            #ifndef CHUNK_H
            #define CHUNK_H

            #include 
            <cassert>

            struct Chunk {
                
            //初始化一個Chunk
                void init(size_t blockSize, unsigned char blocks); 
                
            //分配一個block
                void* allocate(size_t blockSize); 
                
            //回收一個block
                void deallocate(void* p, size_t blockSize); 
                
            //Chunk的起始地址
                unsigned char* pData_; 
                
            //第一個可用的block
                unsigned char firstAvailableBlock_; 
                
            //block的塊數
                unsigned char blocksAvailable_; 
                
            //析構函數釋放內存
                ~Chunk();
            }
            ;

            void Chunk::init(size_t blockSize, unsigned char blocks) {
                
            //從操作系統申請一個Chunk的內存
                pData_ = new unsigned char[blockSize * blocks];
                firstAvailableBlock_ 
            = 0;
                blocksAvailable_ 
            = blocks;
                unsigned 
            char *= pData_;
                
            //每個可用的block存放它下一個可用的block的編號
                for (unsigned char i = 1; i < blocks; i++, p += blockSize) {
                    
            *= i;
                }

            }


            void* Chunk::allocate(size_t blockSize) {
                
            if (blocksAvailable_ == 0return 0;
                unsigned 
            char* pRet = pData_ + (firstAvailableBlock_ * blockSize);
                
            //更新第一個可用的block
                firstAvailableBlock_ = *pRet;
                blocksAvailable_
            --;
                
            return pRet;
            }


            void  Chunk::deallocate(void* p, size_t blockSize) {
                
            //判斷回收的地址是否合法
                assert(p >= pData_);
                unsigned 
            char* toRel = static_cast<unsigned char*>(p);
                
            //判斷是否合法
                assert((toRel - pData_) % blockSize == 0);
                
            *toRel = firstAvailableBlock_;
                firstAvailableBlock_ 
            = static_cast<unsigned char>((toRel - pData_) / blockSize);
                
            //判斷是否產生精度誤差
                assert(firstAvailableBlock_ == ((toRel - pData_) / blockSize));
                blocksAvailable_
            ++;
            }


            Chunk::
            ~Chunk() {
                delete[] pData_;
            }

            #endif


            MemPool.h

            #ifndef MEMPOOL_H
            #define MEMPOOL_H

            #include 
            "Chunk.h"

            struct ChunkList {
                Chunk
            * valChunk_;
                ChunkList
            * next_;
                ChunkList() : valChunk_(
            new Chunk), next_(0{}
                
            ~ChunkList() {delete valChunk_;}
            }
            ;

            class MemPool {
            public :
                MemPool(size_t blockSize);
                
            ~MemPool();
                
            void* alloc(size_t size);
                
            void free(void* p, size_t size);
            private :
                
            //新分配一個Chunk
                ChunkList* allocChunk(); 
                
            //釋放一個Chunk
                void freeChunk(ChunkList* pChunkList);

                
            //一個Chunk所擁有的Block數
                static const int BLOCKS;
                
            //free的Chunk
                ChunkList* headOfChunkList_;
                size_t blockSize_;
            }
            ;

            const int MemPool::BLOCKS = 255;

            MemPool::MemPool(size_t blockSize) : blockSize_(blockSize), headOfChunkList_(
            0{};

            MemPool::
            ~MemPool() {
                
            while (headOfChunkList_) {
                    freeChunk(headOfChunkList_);
                }

            }


            void* MemPool::alloc(size_t size) {
                
            if (size != blockSize_) {
                    
            return ::operator new(size);
                }

                
            //查找可用的Block
                ChunkList* p = headOfChunkList_;
                
            while (p && !p->valChunk_->blocksAvailable_) p = p->next_;

                
            if (!p) p = allocChunk();
                
            void* pRet = p->valChunk_->allocate(blockSize_);
                
            return pRet;
            }



            void MemPool::free(void* p, size_t size) {
                
            if (!p) return ;
                
            if (size != blockSize_) {
                    ::
            operator delete(p);
                    
            return ;
                }

                
            //查找p所屬的Chunk
                ChunkList* pTmp = headOfChunkList_;
                
            while (pTmp) {
                    
            if (p >= pTmp->valChunk_->pData_ && p < pTmp->valChunk_->pData_ + (blockSize_ * BLOCKS)) break;
                    pTmp 
            = pTmp->next_;
                }

                
            if (!pTmp) return ;
                pTmp
            ->valChunk_->deallocate(p, blockSize_);
            }


            ChunkList
            * MemPool::allocChunk() {
                ChunkList
            * pTmpChunkList = new ChunkList;
                
            //新建一個Chunk
                pTmpChunkList->valChunk_->init(blockSize_, BLOCKS);
                
            //把這個Chunk加入到ChunkList的鏈表頭
                pTmpChunkList->next_ = headOfChunkList_;
                headOfChunkList_ 
            = pTmpChunkList;
                
            return pTmpChunkList;
            }


            void MemPool::freeChunk(ChunkList* pChunkList) {
                
            //在鏈表中查找
                if (!pChunkList) return ;
                ChunkList
            * p, * q;
                p 
            = headOfChunkList_;
                q 
            = p->next_;
                
            if (p == pChunkList) {
                    
            //在表頭
                    headOfChunkList_ = p->next_;
                    delete pChunkList;
                    
            return ;
                }

                
            while (q && q != pChunkList) {
                    p 
            = q;
                    q 
            = q->next_;
                }

                
            if (q) {
                    
            //查找成功
                    p->next_ = q->next_;
                    delete pChunkList;
                }

            }



            #endif

            test.cpp
            #include <iostream>
            #include 
            "MemPool.h"
            #include 
            "time.h"
            using namespace std;

            class TestClassA {
            public :
                
            int a;
                
            static void* operator new(size_t size);
                
            static void operator delete(void *p, size_t size);
                
            static MemPool memPool;
            }
            ;

            inline 
            void* TestClassA::operator new(size_t size) {
                
            return memPool.alloc(size);
            }


            inline 
            void TestClassA::operator delete(void* p, size_t size) {
                memPool.free(p, size);
            }


            MemPool TestClassA::memPool(
            sizeof(TestClassA));

            class TestClassB {
            public :
                
            int b;
            }
            ;

            const int CTIMES = 100000;

            TestClassA
            * pa[CTIMES];
            TestClassB
            * pb[CTIMES];

            int main() {
                
            //測試新建100000個SmallObjet所需要的時間
                int i;
                clock_t begB 
            = clock();
                
            for (i=0; i<CTIMES; i++{
                    pb[i] 
            = new TestClassB;
                    }

                clock_t endB 
            = clock();
                printf(
            "Not Used MemPool Time For New = %d ms\n", endB - begB);
                

                clock_t begA 
            = clock();
                
            for (i=0; i<CTIMES; i++{
                    pa[i] 
            = new TestClassA;
                }

                clock_t endA 
            = clock();
                printf(
            "Used MemPool Time For New = %d ms\n", endA - begA);

                
                begB 
            = clock();
                
            for (i=0; i<CTIMES; i++{
                    delete pb[i];
                }

                endB 
            = clock();
                printf(
            "Not Used MemPool Time For Delete = %d ms\n", endB - begB);
                

                begA 
            = clock();
                
            for (i=0; i<CTIMES; i++{
                    delete pa[i];
                }

                endA 
            = clock();
                printf(
            "Used MemPool Time For Delete = %d ms\n", endA - begA);

                
                begB 
            = clock();
                
            for (i=0; i<CTIMES; i++{
                    pb[i] 
            = new TestClassB;
                    delete pb[i];
                }

                endB 
            = clock();
                printf(
            "Not Used MemPool Time For New/Delete = %d ms\n", endB - begB);
                

                begA 
            = clock();
                
            for (i=0; i<CTIMES; i++{
                    pa[i] 
            = new TestClassA;
                    delete pa[i];
                }

                endA 
            = clock();
                printf(
            "Used MemPool Time For New/Delete = %d ms\n", endA - begA);

                
            return 0;
            }


            運行結果:
            Not Used MemPool Time For New = 46 ms
            Used MemPool Time For New = 16 ms
            Not Used MemPool Time For Delete = 47 ms
            Used MemPool Time For Delete = 266 ms
            Not Used MemPool Time For New/Delete = 93 ms
            Used MemPool Time For New/Delete = 16 ms
            Press any key to continue

            可以看到明顯當內存池有大量小對象同時存在的時候,回收的時間很慢,其余時候效果還是不錯的。

            posted on 2008-04-20 17:53 閱讀(656) 評論(0)  編輯 收藏 引用
            久久ZYZ资源站无码中文动漫| 色婷婷久久综合中文久久蜜桃av| 精品久久久久久无码不卡| 国产91久久综合| 国产精久久一区二区三区| 精品免费久久久久国产一区| 国产午夜精品久久久久九九电影| 久久99亚洲综合精品首页| 久久久无码精品亚洲日韩京东传媒 | 看久久久久久a级毛片| 色综合久久久久无码专区| 欧美丰满熟妇BBB久久久| 国产成人久久精品二区三区| 狠狠色丁香久久婷婷综合蜜芽五月 | 久久国产精品久久精品国产| 国产精品综合久久第一页| 色欲综合久久躁天天躁| 日韩精品无码久久久久久| 国产精品伊人久久伊人电影| 欧洲精品久久久av无码电影| 久久久久亚洲精品无码网址| 色综合久久无码五十路人妻| 理论片午午伦夜理片久久| 国产一级持黄大片99久久| 欧美日韩久久中文字幕| 精品久久久久中文字幕一区| 久久青青草原亚洲av无码app| 久久精品国产亚洲av瑜伽| 久久精品无码专区免费东京热| 久久久这里有精品中文字幕| 国产精品久久久久无码av| 7777久久久国产精品消防器材| 狠狠久久综合伊人不卡| 精品久久久久久久| 一本久道久久综合狠狠爱| 思思久久99热免费精品6| AA级片免费看视频久久| 高清免费久久午夜精品| 精品久久久久久成人AV| 久久综合给合久久国产免费 | 无码国内精品久久人妻蜜桃 |