VirtualBox

Changeset 54345 in vbox for trunk/src/VBox/HostDrivers


Ignore:
Timestamp:
Feb 20, 2015 8:27:23 PM (10 years ago)
Author:
vboxsync
Message:

Cleaning up the 2nd algo.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrvGip.cpp

    r54342 r54345  
    111111/** The TSC delta value for the initial GIP master - 0 in regular builds.
    112112 * To test the delta code this can be set to a non-zero value.  */
    113 #if 1
     113#if 0
    114114# define GIP_TSC_DELTA_INITIAL_MASTER_VALUE INT64_C(170139095182512) /* 0x00009abd9854acb0 */
    115115#else
     
    23012301        PSUPDRVTSCDELTAMETHOD2  pWorkerData;
    23022302        uint32_t                cHits;
    2303         /*uint32_t                cOffByOne;*/
    23042303        bool                    fLagMaster;
    23052304        bool                    fLagWorker;
     2305        bool volatile           fQuitEarly;
    23062306    } M2;
    23072307#endif
     
    25252525 * TSC delta measurement algorithm \#2 configuration and code - Experimental!!
    25262526 */
    2527 # undef  GIP_TSC_DELTA_LOOPS
    2528 # undef  GIP_TSC_DELTA_READ_TIME_LOOPS
    2529 # undef  GIP_TSC_DELTA_PRIMER_LOOPS
    2530 # define GIP_TSC_DELTA_LOOPS             17
    2531 # define GIP_TSC_DELTA_PRIMER_LOOPS      1
    2532 # define GIP_TSC_DELTA_READ_TIME_LOOPS   GIP_TSC_DELTA_PRIMER_LOOPS /* no read-time-loops necessary */
    2533 
    2534 
    2535 static void supdrvTscDeltaMethod2ProcessDataSet(PSUPDRVGIPTSCDELTARGS pArgs, PSUPDRVTSCDELTAMETHOD2 pMyData,
    2536                                                 bool fIsMaster, uint32_t cResults,
    2537                                                 PSUPDRVTSCDELTAMETHOD2 pOtherData, int64_t iMasterTscDelta,
    2538                                                 int64_t volatile *piWorkerTscDelta)
    2539 {
    2540     uint32_t cHits      = 0;
    2541 #if 0
    2542     uint32_t cOffByOne  = 0;
    2543 #endif
    2544     uint32_t idxResult  = 0;
    2545     int64_t  iBestDelta = *piWorkerTscDelta;
    2546 
    2547     if (cResults > RT_ELEMENTS(pMyData->aResults))
    2548         cResults = RT_ELEMENTS(pMyData->aResults);
    2549 
    2550     for (idxResult = 0; idxResult < cResults; idxResult++)
    2551     {
    2552         uint32_t idxOther = pMyData->aResults[idxResult].iSeqOther;
     2527
     2528# define GIP_TSC_DELTA_M2_LOOPS             (12 + GIP_TSC_DELTA_M2_PRIMER_LOOPS)
     2529# define GIP_TSC_DELTA_M2_PRIMER_LOOPS      1
     2530
     2531
     2532static void supdrvTscDeltaMethod2ProcessDataOnMaster(PSUPDRVGIPTSCDELTARGS pArgs, uint32_t iLoop)
     2533{
     2534    PSUPDRVTSCDELTAMETHOD2  pMasterData      = pArgs->M2.pMasterData;
     2535    PSUPDRVTSCDELTAMETHOD2  pOtherData       = pArgs->M2.pWorkerData;
     2536    int64_t                 iMasterTscDelta  = pArgs->pMaster->i64TSCDelta;
     2537    int64_t                 iBestDelta       = pArgs->pWorker->i64TSCDelta;
     2538    uint32_t                idxResult;
     2539    uint32_t                cHits            = 0;
     2540
     2541    /*
     2542     * Look for matching entries in the master and worker tables.
     2543     */
     2544    for (idxResult = 0; idxResult < RT_ELEMENTS(pMasterData->aResults); idxResult++)
     2545    {
     2546        uint32_t idxOther = pMasterData->aResults[idxResult].iSeqOther;
    25532547        if (idxOther & 1)
    25542548        {
     
    25562550            if (idxOther < RT_ELEMENTS(pOtherData->aResults))
    25572551            {
    2558                 if (pOtherData->aResults[idxOther].iSeqOther == pMyData->aResults[idxResult].iSeqMine)
     2552                if (pOtherData->aResults[idxOther].iSeqOther == pMasterData->aResults[idxResult].iSeqMine)
    25592553                {
    25602554                    int64_t iDelta;
    2561                     if (fIsMaster)
    2562                         iDelta = pOtherData->aResults[idxOther].uTsc
    2563                                - (pMyData->aResults[idxResult].uTsc - iMasterTscDelta);
    2564                     else
    2565                         iDelta = (pOtherData->aResults[idxResult].uTsc - iMasterTscDelta)
    2566                                - pMyData->aResults[idxOther].uTsc;
     2555                    iDelta = pOtherData->aResults[idxOther].uTsc
     2556                           - (pMasterData->aResults[idxResult].uTsc - iMasterTscDelta);
    25672557                    if (  iDelta >= GIP_TSC_DELTA_INITIAL_MASTER_VALUE
    25682558                        ? iDelta < iBestDelta
     
    25732563            }
    25742564        }
    2575 #if 0  /* Can be used to detect battles between threads on the same core. Decided to change the master instead.  */
    2576         else
    2577         {
    2578             idxOther >>= 1;
    2579             if (   idxOther < RT_ELEMENTS(pOtherData->aResults)
    2580                 && pOtherData->aResults[idxOther].iSeqOther == pMyData->aResults[idxResult].iSeqMine)
    2581                 cOffByOne++;
    2582         }
    2583 #endif
    2584     }
    2585 
    2586     if (cHits > 0)
    2587         *piWorkerTscDelta = iBestDelta;
     2565    }
     2566
     2567    /*
     2568     * Save the results.
     2569     */
     2570    if (cHits > 2)
     2571        pArgs->pWorker->i64TSCDelta = iBestDelta;
    25882572    pArgs->M2.cHits     += cHits;
    2589 #if 0
    2590     pArgs->M2.cOffByOne += cOffByOne;
    2591 #endif
    2592 }
    2593 
    2594 
    2595 static void supdrvTscDeltaMethod2ProcessDataOnMaster(PSUPDRVGIPTSCDELTARGS pArgs)
    2596 {
    2597     supdrvTscDeltaMethod2ProcessDataSet(pArgs,
    2598                                         pArgs->M2.pMasterData,
    2599                                         true /*fIsMaster*/,
    2600                                         RT_ELEMENTS(pArgs->M2.pMasterData->aResults),
    2601                                         pArgs->M2.pWorkerData,
    2602                                         pArgs->pMaster->i64TSCDelta,
    2603                                         &pArgs->pWorker->i64TSCDelta);
    2604 
    2605     supdrvTscDeltaMethod2ProcessDataSet(pArgs,
    2606                                         pArgs->M2.pWorkerData,
    2607                                         false /*fIsMaster*/,
    2608                                         ASMAtomicReadU32(&pArgs->M2.pWorkerData->iCurSeqNo) >> 1,
    2609                                         pArgs->M2.pMasterData,
    2610                                         pArgs->pMaster->i64TSCDelta,
    2611                                         &pArgs->pWorker->i64TSCDelta);
    2612 }
    2613 
     2573
     2574    /*
     2575     * Check and see if we can quit a little early.  If the result is already
     2576     * extremely good (+/-16 ticks seems reasonable), just stop.
     2577     */
     2578    if (  iBestDelta >=   0 + GIP_TSC_DELTA_INITIAL_MASTER_VALUE
     2579        ? iBestDelta <=  16 + GIP_TSC_DELTA_INITIAL_MASTER_VALUE
     2580        : iBestDelta >= -16 + GIP_TSC_DELTA_INITIAL_MASTER_VALUE)
     2581    {
     2582        /*SUPR0Printf("quitting early #1: hits=%#x iLoop=%d iBestDelta=%lld\n", cHits, iLoop, iBestDelta);*/
     2583        ASMAtomicWriteBool(&pArgs->M2.fQuitEarly, true);
     2584    }
     2585    /*
     2586     * After a while, just stop if we get sufficent hits.
     2587     */
     2588    else if (   iLoop >= GIP_TSC_DELTA_M2_LOOPS / 3
     2589             && cHits > 8)
     2590    {
     2591        uint32_t const cHitsNeeded = GIP_TSC_DELTA_M2_LOOPS * RT_ELEMENTS(pArgs->M2.pMasterData->aResults) / 4; /* 25% */
     2592        if (   pArgs->M2.cHits >= cHitsNeeded
     2593            && (  iBestDelta >=  0                                        + GIP_TSC_DELTA_INITIAL_MASTER_VALUE
     2594                ? iBestDelta <=  GIP_TSC_DELTA_THRESHOLD_PRACTICALLY_ZERO + GIP_TSC_DELTA_INITIAL_MASTER_VALUE
     2595                : iBestDelta >= -GIP_TSC_DELTA_THRESHOLD_PRACTICALLY_ZERO + GIP_TSC_DELTA_INITIAL_MASTER_VALUE) )
     2596        {
     2597            /*SUPR0Printf("quitting early hits=%#x (%#x) needed=%#x iLoop=%d iBestDelta=%lld\n",
     2598                        pArgs->M2.cHits, cHits, cHitsNeeded, iLoop, iBestDelta);*/
     2599            ASMAtomicWriteBool(&pArgs->M2.fQuitEarly, true);
     2600        }
     2601    }
     2602}
    26142603
    26152604
     
    26702659{
    26712660    unsigned iLoop;
    2672     for (iLoop = 0; iLoop < GIP_TSC_DELTA_LOOPS; iLoop++)
     2661
     2662    if (fIsMaster)
     2663        ASMAtomicWriteBool(&pArgs->M2.fQuitEarly, false);
     2664
     2665    for (iLoop = 0; iLoop < GIP_TSC_DELTA_M2_LOOPS; iLoop++)
    26732666    {
    26742667        if (fIsMaster)
     
    26792672             * Adjust the loop lag fudge.
    26802673             */
    2681             if (iLoop < GIP_TSC_DELTA_PRIMER_LOOPS)
     2674# if GIP_TSC_DELTA_M2_PRIMER_LOOPS > 0
     2675            if (iLoop < GIP_TSC_DELTA_M2_PRIMER_LOOPS)
    26822676            {
    26832677                /* Lag during the priming to be nice to everyone.. */
     
    26852679                pArgs->M2.fLagWorker = true;
    26862680            }
    2687             else if (iLoop < (GIP_TSC_DELTA_LOOPS - GIP_TSC_DELTA_PRIMER_LOOPS) / 4)
     2681            else
     2682# endif
     2683            if (iLoop < (GIP_TSC_DELTA_M2_LOOPS - GIP_TSC_DELTA_M2_PRIMER_LOOPS) / 4)
    26882684            {
    26892685                /* 25 % of the body without lagging. */
     
    26912687                pArgs->M2.fLagWorker = false;
    26922688            }
    2693             else if (iLoop < (GIP_TSC_DELTA_LOOPS - GIP_TSC_DELTA_PRIMER_LOOPS) / 4 * 2)
     2689            else if (iLoop < (GIP_TSC_DELTA_M2_LOOPS - GIP_TSC_DELTA_M2_PRIMER_LOOPS) / 4 * 2)
    26942690            {
    26952691                /* 25 % of the body with both lagging. */
     
    27142710             * Process the data.
    27152711             */
    2716             if (iLoop > GIP_TSC_DELTA_PRIMER_LOOPS)
    2717                 supdrvTscDeltaMethod2ProcessDataOnMaster(pArgs);
     2712# if GIP_TSC_DELTA_M2_PRIMER_LOOPS > 0
     2713            if (iLoop >= GIP_TSC_DELTA_M2_PRIMER_LOOPS)
     2714# endif
     2715                supdrvTscDeltaMethod2ProcessDataOnMaster(pArgs, iLoop);
    27182716
    27192717            TSCDELTA_MASTER_KICK_OTHER_OUT_OF_AFTER(pSync);
     
    27282726            TSCDELTA_OTHER_SYNC_AFTER(pSync);
    27292727        }
     2728
     2729        if (ASMAtomicReadBool(&pArgs->M2.fQuitEarly))
     2730            break;
     2731
    27302732    }
    27312733}
     
    27602762    RTMemFreeEx(pArgs->M2.pMasterData, sizeof(*pArgs->M2.pMasterData));
    27612763    RTMemFreeEx(pArgs->M2.pWorkerData, sizeof(*pArgs->M2.pWorkerData));
    2762     /*SUPR0Printf("cHits=%d cOffByOne=%d m=%d w=%d\n", pArgs->M2.cHits, pArgs->M2.cOffByOne, pArgs->pMaster->idApic, pArgs->pWorker->idApic);*/
     2764# if 0
     2765    SUPR0Printf("cHits=%d m=%d w=%d\n", pArgs->M2.cHits, pArgs->pMaster->idApic, pArgs->pWorker->idApic);
     2766# endif
    27632767}
    27642768
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