VirtualBox

Changeset 26420 in vbox


Ignore:
Timestamp:
Feb 11, 2010 2:55:04 AM (15 years ago)
Author:
vboxsync
Message:

memcache: some quick tuning.

Location:
trunk/src/VBox/Runtime
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/alloc/memcache.cpp

    r26419 r26420  
    7171     * without taking any locks. */
    7272    PRTMEMCACHEPAGE volatile    pNext;
    73     /** The number of free objects. */
    74     int32_t volatile            cFree;
    75     /** The number of objects on this page.  */
    76     uint32_t                    cObjects;
    7773    /** Bitmap tracking allocated blocks. */
    7874    void volatile              *pbmAlloc;
     
    8177    /** Pointer to the object array.. */
    8278    uint8_t                    *pbObjects;
     79    /** The number of objects on this page.  */
     80    uint32_t                    cObjects;
     81
     82    /** Padding to force cFree into the next cache line. (ASSUMES CL = 64) */
     83    uint8_t                     abPadding[ARCH_BITS == 32 ? 64 - 6*4 : 64 - 5*8 - 4];
     84    /** The number of free objects. */
     85    int32_t volatile            cFree;
    8386} RTMEMCACHEPAGE;
     87AssertCompileMemberOffset(RTMEMCACHEPAGE, cFree, 64);
    8488
    8589
     
    103107    /** The maximum number of objects. */
    104108    uint32_t                    cMax;
    105     /** The total object count. */
    106     uint32_t volatile           cTotal;
    107     /** The number of free objects. */
    108     int32_t volatile            cFree;
    109109    /** Head of the page list. */
    110110    PRTMEMCACHEPAGE             pPageHead;
    111     /** This may point to a page with free entries. */
    112     PRTMEMCACHEPAGE volatile    pPageHint;
    113111    /** Constructor callback. */
    114112    PFNMEMCACHECTOR             pfnCtor;
     
    119117    /** Critical section serializing page allocation and similar. */
    120118    RTCRITSECT                  CritSect;
     119
     120    /** The total object count. */
     121    uint32_t volatile           cTotal;
     122    /** The number of free objects. */
     123    int32_t volatile            cFree;
     124    /** This may point to a page with free entries. */
     125    PRTMEMCACHEPAGE volatile    pPageHint;
    121126} RTMEMCACHEINT;
    122127
     
    161166    pThis->cbAlignment      = cbAlignment;
    162167    pThis->cPerPage         = (PAGE_SIZE - RT_ALIGN_Z(sizeof(RTMEMCACHEPAGE), cbAlignment)) / pThis->cbObject;
    163     while (    RT_ALIGN_Z(sizeof(RTMEMCACHEPAGE), cbAlignment)
     168    while (    RT_ALIGN_Z(sizeof(RTMEMCACHEPAGE), RT_MIN(cbAlignment, 8))
    164169             + pThis->cPerPage * pThis->cbObject
    165              + RT_ALIGN(pThis->cPerPage, 32) * 2
     170             + RT_ALIGN(pThis->cPerPage, 64) / 8 * 2
    166171           > PAGE_SIZE)
    167172        pThis->cPerPage--;
    168     pThis->cBits            = RT_ALIGN(pThis->cPerPage, 32);
     173    pThis->cBits            = RT_ALIGN(pThis->cPerPage, 64);
    169174    pThis->cMax             = cMaxObjects;
    170175    pThis->cTotal           = 0;
     
    236241        /*
    237242         * Allocate and initialize the new page.
     243         *
     244         * We put the constructor bitmap at the lower end right after cFree.
     245         * We then push the object array to the end of the page and place the
     246         * allocation bitmap below it.  The hope is to increase the chance that
     247         * the allocation bitmap is in a different cache line than cFree since
     248         * this increases performance markably when lots of threads are beating
     249         * on the cache.
    238250         */
    239251        PRTMEMCACHEPAGE pPage = (PRTMEMCACHEPAGE)RTMemPageAlloc(PAGE_SIZE);
     
    247259            pPage->cFree        = cObjects;
    248260            pPage->cObjects     = cObjects;
    249             pPage->pbmAlloc     = pPage + 1;
    250             pPage->pbmCtor      = (uint8_t *)pPage->pbmAlloc + pThis->cBits / 8;
    251             pPage->pbObjects    = (uint8_t *)pPage->pbmCtor  + pThis->cBits / 8;
    252             pPage->pbObjects    = RT_ALIGN_PT(pPage->pbObjects, pThis->cbAlignment, uint8_t *);
     261            uint8_t *pb = (uint8_t *)(pPage + 1);
     262            pb = RT_ALIGN_PT(pb, 8, uint8_t *);
     263            pPage->pbmCtor      = pb;
     264            pb += pThis->cBits / 8 * 2;
     265            pb = (uint8_t *)pPage + PAGE_SIZE - pThis->cbObject * cObjects;
     266            pPage->pbObjects    = pb;   Assert(RT_ALIGN_P(pb, pThis->cbAlignment) == pb);
     267            pb -= pThis->cBits / 8;
     268            pb = (uint8_t *)((uintptr_t)pb & ~(uintptr_t)7);
     269            pPage->pbmAlloc     = pb;
     270            Assert((uintptr_t)pPage->pbmCtor + pThis->cBits / 8 < (uintptr_t)pPage->pdmDtor);
    253271
    254272            /* Mark the bitmap padding and any unused objects as allocated. */
     
    309327     */
    310328    int32_t cNewFree = ASMAtomicDecS32(&pThis->cFree);
    311     if (cNewFree < 0)
     329    if (RT_LIKELY(cNewFree < 0))
    312330    {
    313331        uint32_t cTotal = ASMAtomicUoReadU32(&pThis->cTotal);
     
    364382        {
    365383            iObj = ASMBitFirstClear(pPage->pbmAlloc, pThis->cBits);
    366             if (iObj < 0)
     384            if (RT_LIKELY(iObj >= 0))
     385            {
     386                if (!ASMAtomicBitTestAndSet(pPage->pbmAlloc, iObj))
     387                    break;
     388            }
     389            else
    367390                ASMMemoryFence();
    368             else if (!ASMAtomicBitTestAndSet(pPage->pbmAlloc, iObj))
    369                 break;
    370391            Assert(cLoops2 != 40);
    371392        }
     
    424445     */
    425446    PRTMEMCACHEPAGE pPage = (PRTMEMCACHEPAGE)(((uintptr_t)pvObj) & ~(uintptr_t)PAGE_OFFSET_MASK);
    426     AssertReturnVoid(pPage->pCache == pThis);
    427     AssertReturnVoid(ASMAtomicUoReadS32(&pPage->cFree) < (int32_t)pThis->cPerPage);
     447    Assert(pPage->pCache == pThis);
     448    Assert(ASMAtomicUoReadS32(&pPage->cFree) < (int32_t)pThis->cPerPage);
    428449
    429450    /*
     
    432453    uintptr_t offObj = (uintptr_t)pvObj - (uintptr_t)pPage->pbObjects;
    433454    uintptr_t iObj   = offObj / pThis->cbObject;
    434     AssertReturnVoid(iObj * pThis->cbObject == offObj);
     455    Assert(iObj * pThis->cbObject == offObj);
    435456    Assert(iObj < pThis->cPerPage);
    436457    AssertReturnVoid(ASMAtomicBitTestAndClear(pPage->pbmAlloc, iObj));
  • trunk/src/VBox/Runtime/testcase/tstRTMemCache.cpp

    r26419 r26420  
    254254static void tst3(uint32_t cThreads, uint32_t cbObject, bool fUseCache, uint32_t cSecs)
    255255{
    256     RTTestISubF("Benchmark - %u threads, %s", cThreads, fUseCache ? "RTMemCache" : "RTMemAlloc");
     256    RTTestISubF("Benchmark - %u threads, %u bytes, %u secs, %s", cThreads, cbObject, cSecs, fUseCache ? "RTMemCache" : "RTMemAlloc");
    257257
    258258    /*
     
    300300        cIterations += aThreads[i].cIterations;
    301301
    302     RTTestIPrintf(RTTESTLVL_ALWAYS, "%'8u iterations per second\n",
    303                   (unsigned)((long double)cIterations * 1000000000.0 / cElapsedNS));
     302    RTTestIPrintf(RTTESTLVL_ALWAYS, "%'8u iterations per second, %'llu ns on avg\n",
     303                  (unsigned)((long double)cIterations * 1000000000.0 / cElapsedNS),
     304                  cElapsedNS / cIterations);
    304305
    305306    /* clean up */
     
    322323    {
    323324        /*  threads, cbObj, fUseCache, cSecs */
     325        tst3(     1,   256,      true,     5);
     326        tst3(     1,   256,     false,     5);
    324327        tst3(     1,    32,      true,     5);
    325328        tst3(     1,    32,     false,     5);
    326 
     329        tst3(     1,     8,      true,     5);
     330        tst3(     1,     8,     false,     5);
     331        tst3(     1,     2,      true,     5);
     332        tst3(     1,     2,     false,     5);
     333        tst3(     1,     1,      true,     5);
     334        tst3(     1,     1,     false,     5);
     335
     336        tst3(     3,   256,      true,     5);
     337        tst3(     3,   256,     false,     5);
     338        tst3(     3,   128,      true,     5);
     339        tst3(     3,   128,     false,     5);
     340        tst3(     3,    64,      true,     5);
     341        tst3(     3,    64,     false,     5);
    327342        tst3(     3,    32,      true,     5);
    328343        tst3(     3,    32,     false,     5);
     344        tst3(     3,     2,      true,     5);
     345        tst3(     3,     2,     false,     5);
     346        tst3(     3,     1,      true,     5);
     347        tst3(     3,     1,     false,     5);
    329348
    330349        tst3(    16,    32,      true,     5);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette