• <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 袁斌 閱讀(322) 評論(0)  編輯 收藏 引用
            麻豆亚洲AV永久无码精品久久| 久久精品国产第一区二区| 久久黄视频| 精品久久久久久国产| 99久久久精品免费观看国产| 久久精品国产亚洲欧美| 无码国内精品久久人妻麻豆按摩| 精品一二三区久久aaa片| 中文字幕亚洲综合久久2| 久久久艹| 久久99毛片免费观看不卡| 亚洲婷婷国产精品电影人久久| 色偷偷久久一区二区三区| 久久97久久97精品免视看| 伊人久久综合无码成人网| 国内精品欧美久久精品| 少妇久久久久久被弄高潮| 欧美粉嫩小泬久久久久久久| 9久久9久久精品| 精品久久久久久无码不卡| 韩国三级中文字幕hd久久精品| 亚洲午夜久久久久久久久久| 久久伊人中文无码| 国产精品免费久久| 久久久久久久久无码精品亚洲日韩 | 99久久99久久精品国产| 色综合久久无码五十路人妻| 久久精品一区二区影院| 99久久亚洲综合精品成人| 亚洲AV日韩AV永久无码久久| 久久中文字幕人妻熟av女| 亚洲国产小视频精品久久久三级| 中文字幕一区二区三区久久网站| 精品久久久久久久久午夜福利| 亚洲AV成人无码久久精品老人| 久久久午夜精品| 久久久久久免费视频| 欧美亚洲国产精品久久高清| 日本加勒比久久精品| 久久综合亚洲色HEZYO国产| 欧美性大战久久久久久|