VirtualBox

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

memcache: some quick tuning.

File:
1 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));
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