VirtualBox

Ignore:
Timestamp:
Jan 21, 2019 3:15:45 PM (6 years ago)
Author:
vboxsync
Message:

FsPerf: Use PROFILE_FN on write+msync to avoid hacks for bad ext4 performance. Adding cmdline option for duration and iteration count. bugref:9172

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/utils/fs/FsPerf.cpp

    r76919 r76922  
    7575        fsPerfYield(); \
    7676        uint64_t nsStart = RTTimeNanoTS(); \
    77         uint64_t ns; \
     77        uint64_t nsPrf; \
    7878        do \
    79             ns = RTTimeNanoTS(); \
    80         while (ns == nsStart); \
    81         nsStart = ns; \
     79            nsPrf = RTTimeNanoTS(); \
     80        while (nsPrf == nsStart); \
     81        nsStart = nsPrf; \
    8282        \
    8383        uint64_t iIteration = 0; \
     
    8686            RTTESTI_CHECK_RC(a_fnCall, VINF_SUCCESS); \
    8787            iIteration++; \
    88             ns = RTTimeNanoTS() - nsStart; \
    89         } while (ns < RT_NS_10MS || (iIteration & 1)); \
    90         ns /= iIteration; \
    91         if (ns > g_nsPerNanoTSCall + 32) \
    92             ns -= g_nsPerNanoTSCall; \
     88            nsPrf = RTTimeNanoTS() - nsStart; \
     89        } while (nsPrf < RT_NS_10MS || (iIteration & 1)); \
     90        nsPrf /= iIteration; \
     91        if (nsPrf > g_nsPerNanoTSCall + 32) \
     92            nsPrf -= g_nsPerNanoTSCall; \
    9393        \
    94         uint64_t cIterations = (a_cNsTarget) / ns; \
     94        uint64_t cIterations = (a_cNsTarget) / nsPrf; \
    9595        if (cIterations <= 1) \
    9696            cIterations = 2; \
     
    104104        for (; iIteration < cIterations; iIteration++) \
    105105            RTTESTI_CHECK_RC(a_fnCall, VINF_SUCCESS); \
    106         ns = RTTimeNanoTS() - nsStart; \
    107         RTTestIValueF(ns / cIterations, RTTESTUNIT_NS_PER_OCCURRENCE, a_szDesc); \
     106        nsPrf = RTTimeNanoTS() - nsStart; \
     107        RTTestIValue(a_szDesc, nsPrf / cIterations, RTTESTUNIT_NS_PER_OCCURRENCE); \
    108108        if (g_fShowDuration) \
    109             RTTestIValueF(ns, RTTESTUNIT_NS, "%s duration", a_szDesc); \
     109            RTTestIValueF(nsPrf, RTTESTUNIT_NS, "%s duration", a_szDesc); \
     110        if (g_fShowIterations) \
     111            RTTestIValueF(iIteration, RTTESTUNIT_OCCURRENCES, "%s iterations", a_szDesc); \
    110112    } while (0)
    111113
     
    177179        if (g_fShowDuration) \
    178180            RTTestIValueF(ns, RTTESTUNIT_NS, "%s duration", a_szDesc); \
     181        if (g_fShowIterations) \
     182            RTTestIValueF(iIteration, RTTESTUNIT_OCCURRENCES, "%s iterations", a_szDesc); \
    179183    } while (0)
    180184
     
    262266    kCmdOpt_NoMMap,
    263267
     268    kCmdOpt_ShowDuration,
     269    kCmdOpt_NoShowDuration,
     270    kCmdOpt_ShowIterations,
     271    kCmdOpt_NoShowIterations,
    264272    kCmdOpt_End
    265273};
     
    319327    { "--no-mmap",          kCmdOpt_NoMMap,         RTGETOPT_REQ_NOTHING },
    320328
    321     { "--quiet",            'q', RTGETOPT_REQ_NOTHING },
    322     { "--verbose",          'v', RTGETOPT_REQ_NOTHING },
    323     { "--version",          'V', RTGETOPT_REQ_NOTHING },
    324     { "--help",             'h', RTGETOPT_REQ_NOTHING } /* for Usage() */
     329    { "--show-duration",        kCmdOpt_ShowDuration,       RTGETOPT_REQ_NOTHING },
     330    { "--no-show-duration",     kCmdOpt_NoShowDuration,     RTGETOPT_REQ_NOTHING },
     331    { "--show-iterations",      kCmdOpt_ShowIterations,     RTGETOPT_REQ_NOTHING },
     332    { "--no-show-iterations",   kCmdOpt_NoShowIterations,   RTGETOPT_REQ_NOTHING },
     333
     334    { "--quiet",                'q', RTGETOPT_REQ_NOTHING },
     335    { "--verbose",              'v', RTGETOPT_REQ_NOTHING },
     336    { "--version",              'V', RTGETOPT_REQ_NOTHING },
     337    { "--help",                 'h', RTGETOPT_REQ_NOTHING } /* for Usage() */
    325338};
    326339
     
    332345/** Whether or not to display the duration of each profile run.
    333346 * This is chiefly for verify the estimate phase.  */
    334 static bool         g_fShowDuration = true;
     347static bool         g_fShowDuration = false;
     348/** Whether or not to display the iteration count for each profile run.
     349 * This is chiefly for verify the estimate phase.  */
     350static bool         g_fShowIterations = false;
    335351/** Verbosity level. */
    336352static uint32_t     g_uVerbosity = 0;
     
    21352151
    21362152
     2153/**
     2154 * Worker for profiling msync.
     2155 */
     2156DECL_FORCE_INLINE(int) fsPerfMSyncWorker(uint8_t *pbMapping, size_t offMapping, size_t cbFlush, size_t *pcbFlushed)
     2157{
     2158    uint8_t *pbCur = &pbMapping[offMapping];
     2159    for (size_t offFlush = 0; offFlush < cbFlush; offFlush += PAGE_SIZE)
     2160        *(size_t volatile *)&pbCur[offFlush + 8] = cbFlush;
     2161# ifdef RT_OS_WINDOWS
     2162    RTTESTI_CHECK(FlushViewOfFile(pbCur, cbFlush));
     2163# else
     2164    RTTESTI_CHECK(msync(pbCur, cbFlush, MS_SYNC) == 0);
     2165# endif
     2166    if (*pcbFlushed < offMapping + cbFlush)
     2167        *pcbFlushed = offMapping + cbFlush;
     2168    return VINF_SUCCESS;
     2169}
     2170
     2171
    21372172void fsPerfMMap(RTFILE hFile1, RTFILE hFileNoCache, uint64_t cbFile)
    21382173{
     
    22372272                        continue;
    22382273
    2239 # if defined(RT_OS_LINUX)
    2240                     size_t const cFlushes = RT_MIN(cbMapping / cbFlush, 2048);
    2241 # else
    2242                     size_t const cFlushes = cbMapping / cbFlush;
    2243 # endif
    2244                     uint8_t     *pbCur    = pbMapping;
    2245                     ns = RTTimeNanoTS();
    2246                     for (size_t iFlush = 0; iFlush < cFlushes; iFlush++, pbCur += cbFlush)
    2247                     {
    2248                         for (size_t offFlush = 0; offFlush < cbFlush; offFlush += PAGE_SIZE)
    2249                             *(size_t volatile *)&pbCur[offFlush + 8] = cbFlush;
    2250 # ifdef RT_OS_WINDOWS
    2251                         RTTESTI_CHECK(FlushViewOfFile(pbCur, cbFlush));
    2252 # else
    2253                         RTTESTI_CHECK(msync(pbCur, cbFlush, MS_SYNC) == 0);
    2254 # endif
    2255                     }
    2256                     ns = RTTimeNanoTS() - ns;
    2257                     RTTestIValueF(ns / cFlushes, RTTESTUNIT_NS_PER_OCCURRENCE,  "touch/flush/%zu", cbFlush);
     2274                    char szDesc[80];
     2275                    RTStrPrintf(szDesc, sizeof(szDesc), "touch/flush/%zu", cbFlush);
     2276                    size_t const cFlushes      = cbMapping / cbFlush;
     2277                    size_t const cbMappingUsed = cFlushes * cbFlush;
     2278                    size_t       cbFlushed     = 0;
     2279                    PROFILE_FN(fsPerfMSyncWorker(pbMapping, (iIteration * cbFlush) % cbMappingUsed, cbFlush, &cbFlushed),
     2280                               g_nsTestRun, szDesc);
    22582281
    22592282                    /*
     
    22702293                    {
    22712294                        RTTESTI_CHECK_RC(RTFileSeek(hFileNoCache, 0, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS);
    2272                         size_t const cbToCheck = cFlushes * cbFlush;
     2295                        size_t const cbToCheck = RT_MIN(cFlushes * cbFlush, cbFlushed);
    22732296                        unsigned     cErrors   = 0;
    22742297                        for (size_t offBuf = 0; cErrors < 32 && offBuf < cbToCheck; offBuf += cbBuf)
     
    24192442            case 'h':   pszHelp = "Displays this help and exit"; break;
    24202443            case 'V':   pszHelp = "Displays the program revision"; break;
     2444            case kCmdOpt_ShowDuration:      pszHelp =  "Show duration of profile runs. default: --no-show-duration"; break;
     2445            case kCmdOpt_NoShowDuration:    pszHelp =  "Hide duration of profile runs. default: --no-show-duration"; break;
     2446            case kCmdOpt_ShowIterations:    pszHelp =  "Show iteration count for profile runs. default: --no-show-iterations"; break;
     2447            case kCmdOpt_NoShowIterations:  pszHelp =  "Hide iteration count for profile runs. default: --no-show-iterations"; break;
    24212448            default:
    24222449                if (g_aCmdOptions[i].iShort >= kCmdOpt_First)
     
    24812508                rc = RTPathAbs(ValueUnion.psz, g_szDir, sizeof(g_szDir) / 2);
    24822509                if (RT_SUCCESS(rc))
     2510                {
     2511                    RTPathEnsureTrailingSeparator(g_szDir, sizeof(g_szDir));
     2512                    g_cchDir = strlen(g_szDir);
    24832513                    break;
     2514                }
    24842515                RTTestFailed(g_hTest, "RTPathAbs(%s) failed: %Rrc\n", ValueUnion.psz, rc);
    24852516                return RTTestSummaryAndDestroy(g_hTest);
     
    25652596            CASE_OPT(FSync);
    25662597            CASE_OPT(MMap);
     2598
     2599            CASE_OPT(ShowDuration);
     2600            CASE_OPT(ShowIterations);
    25672601#undef CASE_OPT
    25682602
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