• <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、線程關(guān)聯(lián)的內(nèi)存池

             

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

             

            看看第一版線程關(guān)聯(lián)內(nèi)存池的一些代碼:

             

            struct tm_bufunit

            {

                    tm_pool *pool;                        //pool指針

                    union

                    {

                            tm_bufunit *next;   //下一個(gè)塊指針

                            char data[4];           //數(shù)據(jù)區(qū)域

                    };

            };

             

            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;                   //一個(gè)分配塊大小

                    size_t onebknum;            //一次分配多少個(gè)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;

            };

             

            //公開的數(shù)據(jù)及函數(shù)

            extern DWORD tm_tlsindex; //tls索引

             

            //app初始化,分配index

            void tm_init();

            void tm_free();

             

            //關(guān)聯(lián)到該線程

            void tm_attach();

            void tm_detach();

             

            tm_poolset *tm_getpoolset();

            //添加trunk

            bool tm_addtrunk(size_t size, size_t allocnum);

            //tls相關(guān)分配

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

            //tls相關(guān)釋放

            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;

            }

             

            這一版基本實(shí)現(xiàn)了第一步的提速目標(biāo),并且每個(gè)分配塊還記錄了來自哪個(gè)pool,這樣free的時(shí)候就省去了查找pool的動(dòng)作,只是還有一些問題,如何判斷一個(gè)內(nèi)存是來源于malloc的分配還是來源于pool的分配沒有做終結(jié)的判斷,而且還留下了一個(gè)bug,對(duì)于a線程來說,可能只有256512兩個(gè)塊的緩存,b線程可能多一個(gè)塊1024,這樣a線程分配的1024字節(jié)的內(nèi)存是用malloc分配,到b線程釋放的時(shí)候會(huì)調(diào)用pool釋放,這個(gè)bug將在下一章解決。

            Posted on 2010-10-03 14:10 袁斌 閱讀(322) 評(píng)論(0)  編輯 收藏 引用

            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            久久九九全国免费| 老司机国内精品久久久久| 人人狠狠综合久久88成人| 亚洲精品乱码久久久久久不卡| 精品久久久久成人码免费动漫 | 久久久青草久久久青草| 无遮挡粉嫩小泬久久久久久久| aaa级精品久久久国产片| 国产综合精品久久亚洲| 欧美亚洲国产精品久久高清| 久久久WWW成人| 国内精品久久人妻互换| 久久久久国产精品三级网| 国产精品日韩深夜福利久久| 久久人人爽人人爽人人AV| 久久久久亚洲精品无码蜜桃| 麻豆成人久久精品二区三区免费| 久久夜色精品国产欧美乱| 久久99国产精品久久99| 国色天香久久久久久久小说 | 亚洲AV无码成人网站久久精品大| 久久亚洲AV无码精品色午夜麻豆| 久久婷婷五月综合国产尤物app| 国产高潮国产高潮久久久91| 久久久久久国产精品无码下载| 午夜精品久久久久9999高清| 青青青伊人色综合久久| 久久九九久精品国产| 99久久99久久精品国产片果冻 | 国产精品美女久久久| 精品久久人人妻人人做精品| 国产成人综合久久精品红| 一本色道久久88加勒比—综合| 无码超乳爆乳中文字幕久久| 99久久免费只有精品国产| 精品多毛少妇人妻AV免费久久 | 久久99精品国产麻豆蜜芽| 无码精品久久久天天影视 | 久久久久久久久久久精品尤物 | 精品人妻久久久久久888| 人人狠狠综合久久亚洲|