• <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>

            4、線程關聯的內存池

             

            每每想到單線程下內存池飛一般的速度和多線程下蝸牛一般的速度我就不能原諒自己,為什么差這么多,就不能讓多線程下內存分配更快一點嗎?解決方法有了,那就是讓緩存線程化,各個線程有自己私有的緩存,分配的時候預先從當前線程私有緩存分配,分配空了的時候去全局free表取一組freeunit或直接向系統申請一大塊緩存(各個線程緩存完全獨立),不管具體采用什么方式,速度都大幅度的提高了,雖然還是比單線程下內存池慢了許多,不過比前面提到的多線程內存池以及nedmalloc都要快很多,我的實現大概比nedmalloc1.6 ~ 2倍,離單線程下內存池速度也很近了,只是多了些查找線程id比較線程id等動作而已,基本上達到了自己的目標。

             

            看看第一版線程關聯內存池的一些代碼:

             

            struct tm_bufunit

            {

                    tm_pool *pool;                        //pool指針

                    union

                    {

                            tm_bufunit *next;   //下一個塊指針

                            char data[4];           //數據區域

                    };

            };

             

            struct tm_gcontrol

            {

                    tm_bufunit *gfree;

                    CRITICAL_SECTION gcs;

             

                    tm_gcontrol() : gfree(NULL) { InitializeCriticalSection(&gcs); }

                    ~tm_gcontrol()        { DeleteCriticalSection(&gcs); }

                    Inline void lock()     { EnterCriticalSection(&gcs); }

                    Inline void unlock() { LeaveCriticalSection(&gcs); }

                    void free(tm_bufunit *buf)

                    {

                            lock();

                            buf->next = gfree;

                            gfree = buf;

                            unlock();

                    }

            };

             

            struct tm_memblock

            {

                    tm_memblock *next;

            };

             

            class tm_pool

            {

            private:

                    size_t bksize;                   //一個分配塊大小

                    size_t onebknum;            //一次分配多少個bksize

                    DWORD thid;                          //線程id

                    tm_bufunit *next;           //pool中自由塊鏈

                    tm_memblock *mbk;              //trunk

                    tm_gcontrol gcontrol;     //全局free

                   

                    friend tm_poolset;

            private:

                    void expand();

             

            public:

                    tm_pool(size_t size, size_t bknum);

                    ~tm_pool();

             

                    void destroy();

                    void *newobj();

                    static void delobj(void *pbuf);

            };

             

            class tm_poolset

            {

            public:

                    tm_poolset();

                    virtual ~tm_poolset();

             

                    //添加分配池

                    bool addpool(size_t size, size_t allocnum);

                    void *newobj(size_t size, size_t *osize=NULL);

                    void delobj(void *pbuf, size_t size);

                    void destroy();

             

                    tm_pool *findpool(size_t size)

                    {

                            TMPOOLS::iterator it = tmpools.lower_bound(size);

                            if(it != tmpools.end())

                                    return it->second;

                            return NULL;

                    }

            protected:

                    typedef std::map<size_t, tm_pool *> TMPOOLS;

                    TMPOOLS tmpools;

            };

             

            //公開的數據及函數

            extern DWORD tm_tlsindex; //tls索引

             

            //app初始化,分配index

            void tm_init();

            void tm_free();

             

            //關聯到該線程

            void tm_attach();

            void tm_detach();

             

            tm_poolset *tm_getpoolset();

            //添加trunk

            bool tm_addtrunk(size_t size, size_t allocnum);

            //tls相關分配

            void *tm_new(size_t size, size_t *osize=NULL);

            //tls相關釋放

            void tm_del(void *buf, size_t size);

             

             

             

            .cpp代碼如下:

            tm_pool::tm_pool(size_t size, size_t bknum) :

                    next(NULL), mbk(NULL),

                    bksize(size), onebknum(bknum)

            {

                    thid = GetCurrentThreadId();

            }

             

            tm_pool::~tm_pool()

            {

                    destroy();

            }

             

            void tm_pool::destroy()

            {

                    for(tm_memblock *p = mbk; p; )

                    {

                            tm_memblock *q = p->next;

                            free((char *)p);

                            p = q;

                    }

                    mbk = NULL;

                    next = NULL;

            }

             

            void *tm_pool::newobj()

            {

                    if(! next)

                    {

                            gcontrol.lock();

                            if(gcontrol.gfree)

                            {

                                    next = gcontrol.gfree;

                                    gcontrol.gfree = NULL;

                            }

                            gcontrol.unlock();

                    }

                    if(! next)

                    {

                            expand();

                    }

                    tm_bufunit *head = next;

                    next = head->next;

            //     return (void *)head;

                    return (void *)head->data;

            }

             

            void tm_pool::delobj(void *pbuf)

            {

            //     tm_bufunit *head = (tm_bufunit*)(pbuf);

                    tm_bufunit *head = (tm_bufunit *)((char *)pbuf-offsetof(tm_bufunit, data));

                    tm_pool *pool = head->pool;

                    if(pool->thid == GetCurrentThreadId())

                    {

                            head->next = pool->next;

                            pool->next = head;

                    }

                    else

                    {

                            pool->gcontrol.free(head);

                    }

            }

             

            void tm_pool::expand()

            {

                    size_t unitsize = offsetof(tm_bufunit, data) + bksize;

                    size_t size = (unitsize * onebknum + sizeof(tm_memblock));

                    tm_memblock *pbk = (tm_memblock *)malloc(size);

                    pbk->next = mbk;

                    mbk = pbk;

                    tm_bufunit *p = (tm_bufunit*)((char *)pbk+sizeof(tm_memblock));

                    p->pool = this;

                    next = p;

                    for(size_t i=0; i<onebknum-1; ++i)

                    {

                            p->next = (tm_bufunit *)((char *)p+unitsize);

                            p = p->next;

                            p->pool = this;

                    }

                    p->next = NULL;

            }

             

            這一版基本實現了第一步的提速目標,并且每個分配塊還記錄了來自哪個pool,這樣free的時候就省去了查找pool的動作,只是還有一些問題,如何判斷一個內存是來源于malloc的分配還是來源于pool的分配沒有做終結的判斷,而且還留下了一個bug,對于a線程來說,可能只有256,512兩個塊的緩存,b線程可能多一個塊1024,這樣a線程分配的1024字節的內存是用malloc分配,到b線程釋放的時候會調用pool釋放,這個bug將在下一章解決。

            Posted on 2010-10-03 14:10 袁斌 閱讀(323) 評論(0)  編輯 收藏 引用
            日本精品久久久久中文字幕| 久久国产精品久久| 日韩精品无码久久一区二区三| 久久综合狠狠综合久久激情 | 亚洲国产精品人久久| 精品伊人久久久| 丁香狠狠色婷婷久久综合| 97久久精品人人做人人爽| 四虎国产精品成人免费久久| 久久久久久九九99精品| 久久精品国产WWW456C0M| 久久天堂AV综合合色蜜桃网| 99久久精品国产综合一区| 中文字幕久久精品无码| 久久国产成人精品麻豆 | 精品久久久久中文字幕日本| av无码久久久久不卡免费网站| 久久精品国产精品亚洲| 亚洲αv久久久噜噜噜噜噜| 久久精品国产WWW456C0M| 久久精品无码一区二区三区| 国内精品久久国产| 国产精品99久久久久久猫咪| 久久久久人妻一区二区三区| 久久久精品人妻无码专区不卡| 久久综合狠狠综合久久| 久久丫忘忧草产品| 亚洲欧美成人久久综合中文网| 999久久久国产精品| 国产精品久久精品| 国内精品久久久久影院优| 久久久久久曰本AV免费免费| 日韩电影久久久被窝网| 色天使久久综合网天天| 国产精品青草久久久久福利99| 国产成人久久精品激情| 91精品国产9l久久久久| 精品国产VA久久久久久久冰 | 久久精品无码一区二区三区免费| 精品久久久久久亚洲精品 | 久久夜色精品国产|