VirtualBox

Changeset 72579 in vbox


Ignore:
Timestamp:
Jun 16, 2018 2:32:26 PM (7 years ago)
Author:
vboxsync
Message:

EM: Implemented a very simple history record replacement strategy. bugref:9044

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r72570 r72579  
    529529     */
    530530    AssertCompile(RT_ELEMENTS(pVCpu->em.s.aExitRecords) == 1024);
    531 #define EM_EXIT_RECORDS_IDX_MASK 1023
     531#define EM_EXIT_RECORDS_IDX_MASK 0x3ff
    532532    uintptr_t  idxSlot  = ((uintptr_t)uFlatPC >> 1) & EM_EXIT_RECORDS_IDX_MASK;
    533533    PEMEXITREC pExitRec = &pVCpu->em.s.aExitRecords[idxSlot];
     
    537537        pHistEntry->idxSlot = (uint32_t)idxSlot;
    538538        if (pExitRec->uFlagsAndType == uFlagsAndType)
     539        {
    539540            pExitRec->uLastExitNo = uExitNo;
     541            STAM_REL_COUNTER_INC(&pVCpu->em.s.aStatHistoryRecHits[0]);
     542        }
    540543        else
     544        {
     545            STAM_REL_COUNTER_INC(&pVCpu->em.s.aStatHistoryRecTypeChanged[0]);
    541546            return emHistoryRecordInit(pExitRec, uFlatPC, uFlagsAndType, uExitNo);
     547        }
    542548    }
    543549    else if (pExitRec->enmAction == EMEXITACTION_FREE_RECORD)
     550    {
     551        STAM_REL_COUNTER_INC(&pVCpu->em.s.aStatHistoryRecNew[0]);
    544552        return emHistoryRecordInitNew(pVCpu, pHistEntry, idxSlot, pExitRec, uFlatPC, uFlagsAndType, uExitNo);
     553    }
    545554    else
    546555    {
    547556        /*
    548          * Collision. Figure out later.
     557         * Collision.  We calculate a new hash for stepping away from the first,
     558         * doing up to 8 steps away before replacing the least recently used record.
    549559         */
    550         return NULL;
    551     }
    552 
     560        uintptr_t idxOldest     = idxSlot;
     561        uint64_t  uOldestExitNo = pExitRec->uLastExitNo;
     562        unsigned  iOldestStep   = 0;
     563        unsigned  iStep         = 1;
     564        uintptr_t const idxAdd  = (uintptr_t)(uFlatPC >> 11) & (EM_EXIT_RECORDS_IDX_MASK / 4);
     565        for (;;)
     566        {
     567            Assert(iStep < RT_ELEMENTS(pVCpu->em.s.aStatHistoryRecHits));
     568            AssertCompile(RT_ELEMENTS(pVCpu->em.s.aStatHistoryRecNew)         == RT_ELEMENTS(pVCpu->em.s.aStatHistoryRecHits));
     569            AssertCompile(RT_ELEMENTS(pVCpu->em.s.aStatHistoryRecReplaced)    == RT_ELEMENTS(pVCpu->em.s.aStatHistoryRecHits));
     570            AssertCompile(RT_ELEMENTS(pVCpu->em.s.aStatHistoryRecTypeChanged) == RT_ELEMENTS(pVCpu->em.s.aStatHistoryRecHits));
     571
     572            /* Step to the next slot. */
     573            idxSlot += idxAdd;
     574            idxSlot &= EM_EXIT_RECORDS_IDX_MASK;
     575            pExitRec = &pVCpu->em.s.aExitRecords[idxSlot];
     576
     577            /* Does it match? */
     578            if (pExitRec->uFlatPC == uFlatPC)
     579            {
     580                Assert(pExitRec->enmAction != EMEXITACTION_FREE_RECORD);
     581                pHistEntry->idxSlot = (uint32_t)idxSlot;
     582                if (pExitRec->uFlagsAndType == uFlagsAndType)
     583                {
     584                    pExitRec->uLastExitNo = uExitNo;
     585                    STAM_REL_COUNTER_INC(&pVCpu->em.s.aStatHistoryRecHits[iStep]);
     586                    break;
     587                }
     588                STAM_REL_COUNTER_INC(&pVCpu->em.s.aStatHistoryRecTypeChanged[iStep]);
     589                return emHistoryRecordInit(pExitRec, uFlatPC, uFlagsAndType, uExitNo);
     590            }
     591
     592            /* Is it free? */
     593            if (pExitRec->enmAction == EMEXITACTION_FREE_RECORD)
     594            {
     595                STAM_REL_COUNTER_INC(&pVCpu->em.s.aStatHistoryRecNew[iStep]);
     596                return emHistoryRecordInitNew(pVCpu, pHistEntry, idxSlot, pExitRec, uFlatPC, uFlagsAndType, uExitNo);
     597            }
     598
     599            /* Is it the least recently used one? */
     600            if (pExitRec->uLastExitNo < uOldestExitNo)
     601            {
     602                uOldestExitNo = pExitRec->uLastExitNo;
     603                idxOldest     = idxSlot;
     604                iOldestStep   = iStep;
     605            }
     606
     607            /* Next iteration? */
     608            iStep++;
     609            Assert(iStep < RT_ELEMENTS(pVCpu->em.s.aStatHistoryRecReplaced));
     610            if (RT_LIKELY(iStep < 8 + 1))
     611            { /* likely */ }
     612            else
     613            {
     614                /* Replace the least recently used slot. */
     615                STAM_REL_COUNTER_INC(&pVCpu->em.s.aStatHistoryRecReplaced[iOldestStep]);
     616                pExitRec = &pVCpu->em.s.aExitRecords[idxOldest];
     617                return emHistoryRecordInitNew(pVCpu, pHistEntry, idxOldest, pExitRec, uFlatPC, uFlagsAndType, uExitNo);
     618            }
     619        }
     620    }
    553621
    554622    /*
  • trunk/src/VBox/VMM/VMMR3/EM.cpp

    r72565 r72579  
    451451
    452452        rc = STAMR3RegisterF(pVM, &pVCpu->em.s.iNextExit, STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
    453                              "Number of recorded exits (R0/RC).", "/PROF/CPU%u/EM/RecordedExits", i);
     453                             "Number of recorded exits.", "/PROF/CPU%u/EM/RecordedExits", i);
    454454        AssertRC(rc);
    455455
     456        /* History record statistics */
     457        rc = STAMR3RegisterF(pVM, &pVCpu->em.s.cExitRecordUsed, STAMTYPE_U32, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
     458                             "Number of used hash table entries.", "/EM/CPU%u/ExitHashing/Used", i);
     459        AssertRC(rc);
     460
     461        for (uint32_t iStep = 0; iStep < RT_ELEMENTS(pVCpu->em.s.aStatHistoryRecHits); iStep++)
     462        {
     463            rc = STAMR3RegisterF(pVM, &pVCpu->em.s.aStatHistoryRecHits[iStep], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
     464                                 "Number of hits at this step.",             "/EM/CPU%u/ExitHashing/Step%02u-Hits", i, iStep);
     465            AssertRC(rc);
     466            rc = STAMR3RegisterF(pVM, &pVCpu->em.s.aStatHistoryRecTypeChanged[iStep], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
     467                                 "Number of type changes at this step.",     "/EM/CPU%u/ExitHashing/Step%02u-TypeChanges", i, iStep);
     468            AssertRC(rc);
     469            rc = STAMR3RegisterF(pVM, &pVCpu->em.s.aStatHistoryRecTypeChanged[iStep], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
     470                                 "Number of replacments at this step.",     "/EM/CPU%u/ExitHashing/Step%02u-Replacments", i, iStep);
     471            AssertRC(rc);
     472            rc = STAMR3RegisterF(pVM, &pVCpu->em.s.aStatHistoryRecNew[iStep], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
     473                                 "Number of new inserts at this step.",     "/EM/CPU%u/ExitHashing/Step%02u-NewInserts", i, iStep);
     474            AssertRC(rc);
     475        }
    456476    }
    457477
  • trunk/src/VBox/VMM/include/EMInternal.h

    r72576 r72579  
    506506    /** Exit history table (6KB). */
    507507    EMEXITENTRY             aExitHistory[256];
     508
     509    /** Hit statistics for each lookup step. */
     510    STAMCOUNTER             aStatHistoryRecHits[16];
     511    /** Type change statistics for each lookup step. */
     512    STAMCOUNTER             aStatHistoryRecTypeChanged[16];
     513    /** Replacement statistics for each lookup step. */
     514    STAMCOUNTER             aStatHistoryRecReplaced[16];
     515    /** New record statistics for each lookup step. */
     516    STAMCOUNTER             aStatHistoryRecNew[16];
    508517    /** Number of exit records in use. */
    509518    uint32_t                cExitRecordUsed;
    510     /** Number of exit records collisions. */
    511     uint32_t                cExitRecordCollisions;
     519    /** Explicit padding. */
     520    uint32_t                uPadding2;
    512521    /** Exit records (32KB). (Aligned on 32 byte boundrary.) */
    513522    EMEXITREC               aExitRecords[1024];
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