VirtualBox

Changeset 80159 in vbox


Ignore:
Timestamp:
Aug 6, 2019 3:32:11 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
132600
Message:

VMM/TM: More 'info cpuload' improvements.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/TM.cpp

    r80157 r80159  
    856856    DBGFR3InfoRegisterInternalEx(pVM, "activetimers", "Dumps active all timers. No arguments.",   tmR3TimerInfoActive,  DBGFINFO_FLAGS_RUN_ON_EMT);
    857857    DBGFR3InfoRegisterInternalEx(pVM, "clocks",       "Display the time of the various clocks.",  tmR3InfoClocks,       DBGFINFO_FLAGS_RUN_ON_EMT);
    858     DBGFR3InfoRegisterInternalArgv(pVM, "cpuload",    "Display the CPU load stats.",              tmR3InfoCpuLoad,      0);
     858    DBGFR3InfoRegisterInternalArgv(pVM, "cpuload",    "Display the CPU load stats (--help for details).", tmR3InfoCpuLoad, 0);
    859859
    860860    return VINF_SUCCESS;
     
    37823782     */
    37833783    PTMCPULOADSTATE pState      = &pVM->tm.s.CpuLoad;
    3784     VMCPUID         idCpu       = VMCPUID_ALL;
     3784    VMCPUID         idCpu       = 0;
     3785    bool            fAllCpus    = true;
    37853786    bool            fExpGraph   = true;
    3786     uint32_t        cchWidth    = 100;
     3787    uint32_t        cchWidth    = 80;
    37873788    uint32_t        cPeriods    = RT_ELEMENTS(pState->aHistory);
    37883789    uint32_t        cRows       = 60;
     
    37903791    static const RTGETOPTDEF s_aOptions[] =
    37913792    {
     3793        { "all",            'a',    RTGETOPT_REQ_NOTHING },
    37923794        { "cpu",            'c',    RTGETOPT_REQ_UINT32 },
    37933795        { "periods",        'p',    RTGETOPT_REQ_UINT32 },
    3794         { "linear",         'l',    RTGETOPT_REQ_NOTHING },
    37953796        { "rows",           'r',    RTGETOPT_REQ_UINT32 },
     3797        { "uni",            'u',    RTGETOPT_REQ_NOTHING },
     3798        { "uniform",        'u',    RTGETOPT_REQ_NOTHING },
    37963799        { "width",          'w',    RTGETOPT_REQ_UINT32 },
    37973800        { "exp",            'x',    RTGETOPT_REQ_NOTHING },
     
    38003803
    38013804    RTGETOPTSTATE State;
    3802     int rc = RTGetOptInit(&State, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
     3805    int rc = RTGetOptInit(&State, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0 /*fFlags*/);
    38033806    AssertRC(rc);
    38043807
     
    38083811        switch (rc)
    38093812        {
     3813            case 'a':
     3814                pState   = &pVM->aCpus[0].tm.s.CpuLoad;
     3815                idCpu    = 0;
     3816                fAllCpus = true;
     3817                break;
    38103818            case 'c':
    38113819                if (ValueUnion.u32 < pVM->cCpus)
     
    38193827                    idCpu  = VMCPUID_ALL;
    38203828                }
     3829                fAllCpus = false;
    38213830                break;
    38223831            case 'p':
    38233832                cPeriods = RT_MIN(RT_MAX(ValueUnion.u32, 1), RT_ELEMENTS(pState->aHistory));
     3833                break;
     3834            case 'r':
     3835                cRows = RT_MIN(RT_MAX(ValueUnion.u32, 5), RT_ELEMENTS(pState->aHistory));
    38243836                break;
    38253837            case 'w':
     
    38293841                fExpGraph = true;
    38303842                break;
    3831             case 'l':
     3843            case 'u':
    38323844                fExpGraph = false;
    38333845                break;
    3834             case 'r':
    3835                 cRows = RT_MIN(RT_MAX(ValueUnion.u32, 5), RT_ELEMENTS(pState->aHistory));
    3836                 break;
     3846            case 'h':
     3847                pHlp->pfnPrintf(pHlp,
     3848                                "Usage: cpuload [parameters]\n"
     3849                                "  all, -a\n"
     3850                                "    Show statistics for all CPUs. (default)\n"
     3851                                "  cpu=id, -c id\n"
     3852                                "    Show statistics for the specified CPU ID.  Show combined stats if out of range.\n"
     3853                                "  periods=count, -p count\n"
     3854                                "    Number of periods to show.  Default: all\n"
     3855                                "  rows=count, -r count\n"
     3856                                "    Number of rows in the graphs.  Default: 60\n"
     3857                                "  width=count, -w count\n"
     3858                                "    Core graph width in characters. Default: 80\n"
     3859                                "  exp, exponential, -e\n"
     3860                                "    Do 1:1 for more recent half / 30 seconds of the graph, combine the\n"
     3861                                "    rest into increasinly larger chunks.  Default.\n"
     3862                                "  uniform, uni, -u\n"
     3863                                "    Combine periods into rows in a uniform manner for the whole graph.\n");
     3864                return;
    38373865            default:
    38383866                pHlp->pfnGetOptError(pHlp, rc, &ValueUnion, &State);
     
    38423870
    38433871    /*
    3844      * Try do the job.
    3845      */
    3846     uint32_t const cMaxPeriods = pState->cHistoryEntries;
    3847     if (cPeriods > cMaxPeriods)
    3848         cPeriods = cMaxPeriods;
    3849     if (cPeriods > 0)
    3850     {
    3851         /*
    3852          * Figure number of periods per chunk.  We can either do this in a linear
    3853          * fashion or a exponential fashion that compresses old history more.
    3854          */
    3855         size_t cPeriodsPerRow = 1;
    3856         if (cRows < cPeriods)
     3872     * Do the job.
     3873     */
     3874    for (;;)
     3875    {
     3876        uint32_t const cMaxPeriods = pState->cHistoryEntries;
     3877        if (cPeriods > cMaxPeriods)
     3878            cPeriods = cMaxPeriods;
     3879        if (cPeriods > 0)
    38573880        {
    3858             if (fExpGraph)
     3881            if (fAllCpus)
    38593882            {
    3860                 /* The last 30 seconds or half of the rows are 1:1, the other part
    3861                    is in increasing period counts.  Code is a little simple but seems
    3862                    to do the job most of the time, which is all I have time now. */
    3863                 size_t cPeriodsOneToOne = RT_MIN(30, cRows / 2);
    3864                 size_t cRestRows        = cRows    - cPeriodsOneToOne;
    3865                 size_t cRestPeriods     = cPeriods - cPeriodsOneToOne;
    3866 
    3867                 size_t cPeriodsInWindow = 0;
    3868                 for (cPeriodsPerRow = 0; cPeriodsPerRow <= cRestRows && cPeriodsInWindow < cRestPeriods; cPeriodsPerRow++)
    3869                     cPeriodsInWindow += cPeriodsPerRow + 1;
    3870 
    3871                 size_t iLower = 1;
    3872                 while (cPeriodsInWindow < cRestPeriods)
     3883                if (idCpu > 0)
     3884                    pHlp->pfnPrintf(pHlp, "\n");
     3885                pHlp->pfnPrintf(pHlp, "    CPU load for virtual CPU %#04x\n"
     3886                                      "    -------------------------------\n", idCpu);
     3887            }
     3888
     3889            /*
     3890             * Figure number of periods per chunk.  We can either do this in a linear
     3891             * fashion or a exponential fashion that compresses old history more.
     3892             */
     3893            size_t cPerRowDecrement = 0;
     3894            size_t cPeriodsPerRow   = 1;
     3895            if (cRows < cPeriods)
     3896            {
     3897                if (!fExpGraph)
     3898                    cPeriodsPerRow   = (cPeriods + cRows / 2) / cRows;
     3899                else
    38733900                {
    3874                     cPeriodsPerRow++;
    3875                     cPeriodsInWindow += cPeriodsPerRow;
    3876                     cPeriodsInWindow -= iLower;
    3877                     iLower++;
     3901                    /* The last 30 seconds or half of the rows are 1:1, the other part
     3902                       is in increasing period counts.  Code is a little simple but seems
     3903                       to do the job most of the time, which is all I have time now. */
     3904                    size_t cPeriodsOneToOne = RT_MIN(30, cRows / 2);
     3905                    size_t cRestRows        = cRows    - cPeriodsOneToOne;
     3906                    size_t cRestPeriods     = cPeriods - cPeriodsOneToOne;
     3907
     3908                    size_t cPeriodsInWindow = 0;
     3909                    for (cPeriodsPerRow = 0; cPeriodsPerRow <= cRestRows && cPeriodsInWindow < cRestPeriods; cPeriodsPerRow++)
     3910                        cPeriodsInWindow += cPeriodsPerRow + 1;
     3911
     3912                    size_t iLower = 1;
     3913                    while (cPeriodsInWindow < cRestPeriods)
     3914                    {
     3915                        cPeriodsPerRow++;
     3916                        cPeriodsInWindow += cPeriodsPerRow;
     3917                        cPeriodsInWindow -= iLower;
     3918                        iLower++;
     3919                    }
     3920
     3921                    cPerRowDecrement = 1;
    38783922                }
    38793923            }
    3880             else
     3924
     3925            /*
     3926             * Do the work.
     3927             */
     3928            size_t cPctExecuting       = 0;
     3929            size_t cPctOther           = 0;
     3930            size_t cPeriodsAccumulated = 0;
     3931
     3932            size_t cRowsLeft = cRows;
     3933            size_t iHistory  = (pState->idxHistory - cPeriods) % RT_ELEMENTS(pState->aHistory);
     3934            while (cPeriods-- > 0)
    38813935            {
    3882                 cPeriodsPerRow   = (cPeriods + cRows / 2) / cRows;
     3936                iHistory++;
     3937                if (iHistory >= RT_ELEMENTS(pState->aHistory))
     3938                    iHistory = 0;
     3939
     3940                cPctExecuting        += pState->aHistory[iHistory].cPctExecuting;
     3941                cPctOther            += pState->aHistory[iHistory].cPctOther;
     3942                cPeriodsAccumulated  += 1;
     3943                if (   cPeriodsAccumulated >= cPeriodsPerRow
     3944                    || cPeriods < cRowsLeft)
     3945                {
     3946                    /*
     3947                     * Format and output the line.
     3948                     */
     3949                    size_t offTmp = 0;
     3950                    size_t i      = tmR3InfoCpuLoadAdjustWidth(cPctExecuting / cPeriodsAccumulated, cchWidth);
     3951                    while (i-- > 0)
     3952                        szTmp[offTmp++] = '#';
     3953                    i = tmR3InfoCpuLoadAdjustWidth(cPctOther / cPeriodsAccumulated, cchWidth);
     3954                    while (i-- > 0)
     3955                        szTmp[offTmp++] = 'O';
     3956                    szTmp[offTmp] = '\0';
     3957
     3958                    cRowsLeft--;
     3959                    pHlp->pfnPrintf(pHlp, "%3zus: %s\n", cPeriods + cPeriodsAccumulated / 2, szTmp);
     3960
     3961                    /* Reset the state: */
     3962                    cPctExecuting       = 0;
     3963                    cPctOther           = 0;
     3964                    cPeriodsAccumulated = 0;
     3965                    if (cPeriodsPerRow > cPerRowDecrement)
     3966                        cPeriodsPerRow -= cPerRowDecrement;
     3967                }
    38833968            }
     3969            pHlp->pfnPrintf(pHlp, "    (#=guest, O=VMM overhead)  idCpu=%#x\n", idCpu);
     3970
    38843971        }
     3972        else
     3973            pHlp->pfnPrintf(pHlp, "No load data.\n");
    38853974
    38863975        /*
    3887          * Do the work.
     3976         * Next CPU if we're display all.
    38883977         */
    3889         size_t cPctExecuting       = 0;
    3890         size_t cPctOther           = 0;
    3891         size_t cPeriodsAccumulated = 0;
    3892 
    3893         size_t cRowsLeft = cRows;
    3894         size_t iHistory  = (pState->idxHistory - cPeriods) % RT_ELEMENTS(pState->aHistory);
    3895         while (cPeriods-- > 0)
    3896         {
    3897             iHistory++;
    3898             if (iHistory >= RT_ELEMENTS(pState->aHistory))
    3899                 iHistory = 0;
    3900 
    3901             cPctExecuting        += pState->aHistory[iHistory].cPctExecuting;
    3902             cPctOther            += pState->aHistory[iHistory].cPctOther;
    3903             cPeriodsAccumulated  += 1;
    3904             if (   cPeriodsAccumulated >= cPeriodsPerRow
    3905                 || cPeriods < cRowsLeft)
    3906             {
    3907                 /*
    3908                  * Format and output the line.
    3909                  */
    3910                 size_t offTmp = 0;
    3911                 size_t i      = tmR3InfoCpuLoadAdjustWidth(cPctExecuting / cPeriodsAccumulated, cchWidth);
    3912                 while (i-- > 0)
    3913                     szTmp[offTmp++] = '#';
    3914                 i = tmR3InfoCpuLoadAdjustWidth(cPctOther / cPeriodsAccumulated, cchWidth);
    3915                 while (i-- > 0)
    3916                     szTmp[offTmp++] = 'O';
    3917                 szTmp[offTmp] = '\0';
    3918 
    3919                 cRowsLeft--;
    3920                 pHlp->pfnPrintf(pHlp, "%3zus: %s\n", cPeriods + cPeriodsAccumulated / 2, szTmp);
    3921 
    3922                 /* Reset the state: */
    3923                 cPctExecuting       = 0;
    3924                 cPctOther           = 0;
    3925                 cPeriodsAccumulated = 0;
    3926                 if (cPeriodsPerRow > 1)
    3927                     cPeriodsPerRow--;
    3928             }
    3929         }
    3930         pHlp->pfnPrintf(pHlp, "  (#=guest, O=VMM overhead)\n");
    3931 
    3932     }
    3933     else
    3934         pHlp->pfnPrintf(pHlp, "No load data.\n");
     3978        if (!fAllCpus)
     3979            break;
     3980        idCpu++;
     3981        if (idCpu >= pVM->cCpus)
     3982            break;
     3983        pState   = &pVM->aCpus[idCpu].tm.s.CpuLoad;
     3984    }
     3985
    39353986}
    39363987
Note: See TracChangeset for help on using the changeset viewer.

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