VirtualBox

Changeset 14850 in vbox


Ignore:
Timestamp:
Dec 1, 2008 11:16:13 AM (16 years ago)
Author:
vboxsync
Message:

PGMR0DynMap: statistics and tuning of autoset insertion.

Location:
trunk/src/VBox/VMM
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PGM.cpp

    r14755 r14850  
    15951595    STAM_REG(pVM, &pPGM->StatR3DynRamTotal,                 STAMTYPE_COUNTER, "/PGM/DynAlloc/TotalAlloc",           STAMUNIT_MEGABYTES,      "Allocated MBs of guest ram.");
    15961596    STAM_REG(pVM, &pPGM->StatR3DynRamGrow,                  STAMTYPE_COUNTER, "/PGM/DynAlloc/Grow",                 STAMUNIT_OCCURENCES,     "Nr of pgmr3PhysGrowRange calls.");
     1597
     1598    /* R0 only: */
     1599    STAM_REG(pVM, &pPGM->StatR0DynMapPage,                  STAMTYPE_COUNTER, "/PGM/R0/DynMapPage" ,                STAMUNIT_OCCURENCES,     "Calls to pgmR0DynMapPage");
     1600    STAM_REG(pVM, &pPGM->StatR0DynMapPageSlow,              STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/Slow" ,           STAMUNIT_OCCURENCES,     "Calls to pgmR0DynMapPageSlow - subtract this from pgmR0DynMapPage to get 1st level hits.");
     1601    STAM_REG(pVM, &pPGM->StatR0DynMapPageSlowLoopHits,      STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/SlowLoopHits" ,   STAMUNIT_OCCURENCES,     "Hits in the loop path.");
     1602    STAM_REG(pVM, &pPGM->StatR0DynMapPageSlowLoopMisses,    STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/SlowLoopMisses",  STAMUNIT_OCCURENCES,     "Misses in the loop path. NonLoopMisses = Slow - SlowLoopHit - SlowLoopMisses");
     1603    STAM_REG(pVM, &pPGM->StatR0DynMapHCPage,                STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/HCPage",          STAMUNIT_OCCURENCES,     "Calls to PGMDynMapHCPage (ring-0).");
     1604    STAM_REG(pVM, &pPGM->StatR0DynMapHCPageSetOptimize,     STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/HCPageSetOptimize", STAMUNIT_OCCURENCES,   "Calls to pgmDynMapOptimizeAutoSet.");
     1605    STAM_REG(pVM, &pPGM->StatR0DynMapHCPageSetSearchHits,   STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/HCPageSetSearchHits", STAMUNIT_OCCURENCES, "Set search hits.");
     1606    STAM_REG(pVM, &pPGM->StatR0DynMapHCPageSetSearchMisses, STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/HCPageSetSearchMisses", STAMUNIT_OCCURENCES, "Set search misses.");
    15971607
    15981608    /* GC only: */
  • trunk/src/VBox/VMM/PGMInternal.h

    r14755 r14850  
    25602560    STAMCOUNTER StatR3DynRamGrow;                   /**< R3: Nr of pgmr3PhysGrowRange calls. */
    25612561
     2562    /* R0 only: */
     2563    STAMCOUNTER StatR0DynMapPage;                   /**< R0: Calls to pgmR0DynMapPage. */
     2564    STAMCOUNTER StatR0DynMapPageSlow;               /**< R0: Calls to pgmR0DynMapPageSlow. */
     2565    STAMCOUNTER StatR0DynMapPageSlowLoopHits;       /**< R0: Hits in the pgmR0DynMapPageSlow search loop. */
     2566    STAMCOUNTER StatR0DynMapPageSlowLoopMisses;     /**< R0: Misses in the pgmR0DynMapPageSlow search loop. */
     2567    STAMCOUNTER StatR0DynMapHCPage;                 /**< R0: Calls to PGMDynMapHCPage. */
     2568    STAMCOUNTER StatR0DynMapHCPageSetOptimize;      /**< R0: Calls to pgmDynMapOptimizeAutoSet. */
     2569    STAMCOUNTER StatR0DynMapHCPageSetSearchHits;    /**< R0: Set search hits. */
     2570    STAMCOUNTER StatR0DynMapHCPageSetSearchMisses;  /**< R0: Set search misses. */
     2571
    25622572    /* RC only: */
    25632573    STAMCOUNTER StatRCDynMapCacheMisses;            /**< RC: The number of dynamic page mapping cache hits */
  • trunk/src/VBox/VMM/VMMR0/PGMR0DynMap.cpp

    r14826 r14850  
    11661166 * @param   HCPhys      The address of the page to be mapped.
    11671167 * @param   iPage       The page index pgmR0DynMapPage hashed HCPhys to.
    1168  */
    1169 static uint32_t pgmR0DynMapPageSlow(PPGMR0DYNMAP pThis, RTHCPHYS HCPhys, uint32_t iPage)
    1170 {
     1168 * @param   pVM         The shared VM structure, for statistics only.
     1169 */
     1170static uint32_t pgmR0DynMapPageSlow(PPGMR0DYNMAP pThis, RTHCPHYS HCPhys, uint32_t iPage, PVM pVM)
     1171{
     1172    STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageSlow);
     1173
    11711174    /*
    11721175     * Check if any of the first 5 pages are unreferenced since the caller
     
    11951198        {
    11961199            if (paPages[iFreePage].HCPhys == HCPhys)
     1200            {
     1201                STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageSlowLoopHits);
    11971202                return iFreePage;
     1203            }
    11981204            if (!paPages[iFreePage].cRefs)
    11991205                break;
     
    12041210                return UINT32_MAX;
    12051211        }
     1212        STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageSlowLoopMisses);
    12061213    }
    12071214    Assert(iFreePage < cPages);
     
    12461253 * @param   pThis       The dynamic mapping cache instance.
    12471254 * @param   HCPhys      The address of the page to be mapped.
    1248  * @param   ppvPage      Where to the page address.
    1249  */
    1250 DECLINLINE(uint32_t) pgmR0DynMapPage(PPGMR0DYNMAP pThis, RTHCPHYS HCPhys, void **ppvPage)
     1255 * @param   pVM         The shared VM structure, for statistics only.
     1256 * @param   ppvPage     Where to the page address.
     1257 */
     1258DECLINLINE(uint32_t) pgmR0DynMapPage(PPGMR0DYNMAP pThis, RTHCPHYS HCPhys, PVM pVM, void **ppvPage)
    12511259{
    12521260    RTSPINLOCKTMP   Tmp       = RTSPINLOCKTMP_INITIALIZER;
    12531261    RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
    12541262    AssertMsg(!(HCPhys & PAGE_OFFSET_MASK), ("HCPhys=%RHp\n", HCPhys));
     1263    STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPage);
    12551264
    12561265    /*
     
    12791288                    if (paPages[iPage2].HCPhys != HCPhys)
    12801289                    {
    1281                         iPage = pgmR0DynMapPageSlow(pThis, HCPhys, iPage);
     1290                        iPage = pgmR0DynMapPageSlow(pThis, HCPhys, iPage, pVM);
    12821291                        if (RT_UNLIKELY(iPage == UINT32_MAX))
    12831292                        {
     
    16201629     * Validate state.
    16211630     */
     1631    STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapHCPage);
    16221632    AssertPtr(ppv);
    16231633    *ppv = NULL;
     
    16351645     * Map it.
    16361646     */
    1637     uint32_t const  iPage = pgmR0DynMapPage(g_pPGMR0DynMap, HCPhys, ppv);
     1647    uint32_t const  iPage = pgmR0DynMapPage(g_pPGMR0DynMap, HCPhys, pVM, ppv);
    16381648    if (RT_UNLIKELY(iPage == UINT32_MAX))
    16391649    {
     
    16471657    /*
    16481658     * Add the page to the auto reference set.
    1649      * If it's less than half full, don't bother looking for duplicates.
    1650      */
    1651     if (pSet->cEntries < RT_ELEMENTS(pSet->aEntries) / 2)
     1659     *
     1660     * The typical usage pattern means that the same pages will be mapped
     1661     * several times in the same set. We can catch most of these
     1662     * remappings by looking a few pages back into the set. (The searching
     1663     * and set optimizing path will hardly ever be used when doing this.)
     1664     */
     1665    AssertCompile(RT_ELEMENTS(pSet->aEntries) >= 8);
     1666    int32_t i = pSet->cEntries;
     1667    if (i-- < 5)
    16521668    {
    16531669        pSet->aEntries[pSet->cEntries].cRefs = 1;
     
    16551671        pSet->cEntries++;
    16561672    }
     1673    /* Any of the last 5 pages? */
     1674    else if (   pSet->aEntries[i - 0].iPage == iPage
     1675             && pSet->aEntries[i - 0].cRefs < UINT16_MAX - 1)
     1676        pSet->aEntries[i - 0].cRefs++;
     1677    else if (   pSet->aEntries[i - 1].iPage == iPage
     1678             && pSet->aEntries[i - 1].cRefs < UINT16_MAX - 1)
     1679        pSet->aEntries[i - 1].cRefs++;
     1680    else if (   pSet->aEntries[i - 2].iPage == iPage
     1681             && pSet->aEntries[i - 2].cRefs < UINT16_MAX - 1)
     1682        pSet->aEntries[i - 2].cRefs++;
     1683    else if (   pSet->aEntries[i - 3].iPage == iPage
     1684             && pSet->aEntries[i - 3].cRefs < UINT16_MAX - 1)
     1685        pSet->aEntries[i - 3].cRefs++;
     1686    else if (   pSet->aEntries[i - 4].iPage == iPage
     1687             && pSet->aEntries[i - 4].cRefs < UINT16_MAX - 1)
     1688        pSet->aEntries[i - 4].cRefs++;
     1689    /* Don't bother searching unless we're above a 75% load. */
     1690    else if (i <= (int32_t)RT_ELEMENTS(pSet->aEntries) / 4 * 3)
     1691    {
     1692        pSet->aEntries[pSet->cEntries].cRefs = 1;
     1693        pSet->aEntries[pSet->cEntries].iPage = iPage;
     1694        pSet->cEntries++;
     1695    }
    16571696    else
    16581697    {
     1698        /* Search the rest of the set. */
    16591699        Assert(pSet->cEntries <= RT_ELEMENTS(pSet->aEntries));
    1660         int32_t     i = pSet->cEntries;
     1700        i -= 4;
    16611701        while (i-- > 0)
    16621702            if (    pSet->aEntries[i].iPage == iPage
     
    16641704            {
    16651705                pSet->aEntries[i].cRefs++;
     1706                STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapHCPageSetSearchHits);
    16661707                break;
    16671708            }
    16681709        if (i < 0)
    16691710        {
     1711            STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapHCPageSetSearchMisses);
    16701712            if (RT_UNLIKELY(pSet->cEntries >= RT_ELEMENTS(pSet->aEntries)))
     1713            {
     1714                STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapHCPageSetOptimize);
    16711715                pgmDynMapOptimizeAutoSet(pSet);
     1716            }
    16721717            if (RT_LIKELY(pSet->cEntries < RT_ELEMENTS(pSet->aEntries)))
    16731718            {
     
    17701815        LogRel(("Test #2\n"));
    17711816        ASMIntDisable();
    1772         for (i = 0 ; i < UINT16_MAX*2 + RT_ELEMENTS(pSet->aEntries) / 2 && RT_SUCCESS(rc) && pv2 == pv; i++)
     1817        for (i = 0 ; i < UINT16_MAX*2 - 1 && RT_SUCCESS(rc) && pv2 == pv; i++)
    17731818        {
    17741819            pv2 = (void *)(intptr_t)-4;
     
    17811826            if (RT_SUCCESS(rc)) rc = VERR_INTERNAL_ERROR;
    17821827        }
    1783         else if (pSet->cEntries != RT_ELEMENTS(pSet->aEntries) / 2)
     1828        else if (pSet->cEntries != 5)
    17841829        {
    17851830            LogRel(("failed(%d): cEntries=%d expected %d\n", __LINE__, pSet->cEntries, RT_ELEMENTS(pSet->aEntries) / 2));
    17861831            rc = VERR_INTERNAL_ERROR;
    17871832        }
    1788         else if (   pSet->aEntries[(RT_ELEMENTS(pSet->aEntries) / 2) - 1].cRefs != UINT16_MAX - 1
    1789                  || pSet->aEntries[(RT_ELEMENTS(pSet->aEntries) / 2) - 2].cRefs != UINT16_MAX - 1
    1790                  || pSet->aEntries[(RT_ELEMENTS(pSet->aEntries) / 2) - 3].cRefs != 2+2+3
    1791                  || pSet->aEntries[(RT_ELEMENTS(pSet->aEntries) / 2) - 4].cRefs != 1)
     1833        else if (   pSet->aEntries[4].cRefs != UINT16_MAX - 1
     1834                 || pSet->aEntries[3].cRefs != UINT16_MAX - 1
     1835                 || pSet->aEntries[2].cRefs != 1
     1836                 || pSet->aEntries[1].cRefs != 1
     1837                 || pSet->aEntries[0].cRefs != 1)
    17921838        {
    17931839            LogRel(("failed(%d): bad set dist: ", __LINE__));
     
    18071853            ASMIntDisable();
    18081854            pv2 = NULL;
    1809             for (i = 0 ; i < RT_ELEMENTS(pSet->aEntries) / 2 && RT_SUCCESS(rc) && pv2 != pv; i++)
     1855            for (i = 0 ; i < RT_ELEMENTS(pSet->aEntries) - 5 && RT_SUCCESS(rc) && pv2 != pv; i++)
    18101856            {
    18111857                pv2 = (void *)(intptr_t)(-5 - i);
     
    18331879                LogRel(("Test #4\n"));
    18341880                ASMIntDisable();
    1835                 for (i = 0 ; i < RT_ELEMENTS(pSet->aEntries) / 2 - 3 + 1 && pv2 != pv; i++)
     1881                for (i = 0 ; i < RT_ELEMENTS(pSet->aEntries) + 2; i++)
    18361882                {
    18371883                    rc = PGMDynMapHCPage(pVM, cr3 - PAGE_SIZE * (i + 5), &pv2);
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