• <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
            <2006年9月>
            272829303112
            3456789
            10111213141516
            17181920212223
            24252627282930
            1234567

            潛心看書研究!

            常用鏈接

            留言簿(19)

            隨筆分類(81)

            文章分類(89)

            相冊

            ACM OJ

            My friends

            搜索

            •  

            積分與排名

            • 積分 - 216403
            • 排名 - 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 閱讀(654) 評論(0)  編輯 收藏 引用
            18岁日韩内射颜射午夜久久成人| 久久亚洲高清综合| 国产精品一区二区久久精品无码 | 国产真实乱对白精彩久久| 精品久久久久久无码专区不卡| 久久久久久久久久免免费精品| 国产精品亚洲美女久久久| 国产精品九九九久久九九| 无码人妻少妇久久中文字幕蜜桃| 国产成人综合久久精品红| 久久婷婷午色综合夜啪| 思思久久99热只有频精品66| 久久精品国产99久久香蕉| 久久天天日天天操综合伊人av| 欧美亚洲另类久久综合婷婷 | 久久人人爽人人人人爽AV| 久久久久亚洲精品日久生情| 久久精品国产99国产精品导航| 亚洲国产美女精品久久久久∴| 性高湖久久久久久久久| 国产∨亚洲V天堂无码久久久 | 久久久久久久人妻无码中文字幕爆| 浪潮AV色综合久久天堂| 成人久久精品一区二区三区| 久久这里只精品国产99热| 久久av高潮av无码av喷吹| 久久久久亚洲av成人无码电影| 久久五月精品中文字幕| 精品人妻伦一二三区久久| 国产精品久久久久久久久鸭| 久久只有这里有精品4| 久久精品中文字幕一区| 日批日出水久久亚洲精品tv| 亚洲国产精品综合久久网络| 精品国产乱码久久久久久浪潮| 久久99精品久久久久久野外| 久久精品桃花综合| 成人免费网站久久久| 久久无码一区二区三区少妇| 亚洲欧美久久久久9999| 国产精品99久久不卡|