VirtualBox

Changeset 76999 in vbox for trunk


Ignore:
Timestamp:
Jan 26, 2019 12:24:28 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
128421
Message:

FsPerf: More command line options for tweaking the test parameters. bugref:9172

File:
1 edited

Legend:

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

    r76975 r76999  
    267267    kCmdOpt_MMap,
    268268    kCmdOpt_NoMMap,
     269    kCmdOpt_IgnoreNoCache,
     270    kCmdOpt_NoIgnoreNoCache,
     271    kCmdOpt_IoFileSize,
     272    kCmdOpt_SetBlockSize,
     273    kCmdOpt_AddBlockSize,
    269274
    270275    kCmdOpt_ShowDuration,
     
    272277    kCmdOpt_ShowIterations,
    273278    kCmdOpt_NoShowIterations,
     279
     280    kCmdOpt_ManyTreeFilesPerDir,
     281    kCmdOpt_ManyTreeSubdirsPerDir,
     282    kCmdOpt_ManyTreeDepth,
     283
    274284    kCmdOpt_End
    275285};
     
    289299    { "--disable-all",      'z', RTGETOPT_REQ_NOTHING },
    290300
    291     { "--many-files",       kCmdOpt_ManyFiles,      RTGETOPT_REQ_NOTHING },
    292     { "--no-many-files",    kCmdOpt_NoManyFiles,    RTGETOPT_REQ_NOTHING },
     301    { "--many-files",       kCmdOpt_ManyFiles,              RTGETOPT_REQ_UINT32 },
     302    { "--no-many-files",    kCmdOpt_NoManyFiles,            RTGETOPT_REQ_NOTHING },
     303    { "--files-per-dir",    kCmdOpt_ManyTreeFilesPerDir,    RTGETOPT_REQ_UINT32 },
     304    { "--subdirs-per-dir",  kCmdOpt_ManyTreeSubdirsPerDir,  RTGETOPT_REQ_UINT32 },
     305    { "--tree-depth",       kCmdOpt_ManyTreeDepth,          RTGETOPT_REQ_UINT32 },
    293306
    294307    { "--open",             kCmdOpt_Open,           RTGETOPT_REQ_NOTHING },
     
    328341    { "--mmap",             kCmdOpt_MMap,           RTGETOPT_REQ_NOTHING },
    329342    { "--no-mmap",          kCmdOpt_NoMMap,         RTGETOPT_REQ_NOTHING },
     343    { "--ignore-no-cache",  kCmdOpt_IgnoreNoCache,  RTGETOPT_REQ_NOTHING },
     344    { "--no-ignore-no-cache",  kCmdOpt_NoIgnoreNoCache,  RTGETOPT_REQ_NOTHING },
     345    { "--io-file-size",     kCmdOpt_IoFileSize,     RTGETOPT_REQ_UINT64 },
     346    { "--set-block-size",   kCmdOpt_SetBlockSize,   RTGETOPT_REQ_UINT32 },
     347    { "--add-block-size",   kCmdOpt_AddBlockSize,   RTGETOPT_REQ_UINT32 },
    330348
    331349    { "--show-duration",        kCmdOpt_ShowDuration,       RTGETOPT_REQ_NOTHING },
     
    387405/** Number of files per directory in the 'manytree' construct. */
    388406static uint32_t     g_cManyTreeFilesPerDir      = 640;
    389 /* Number of subdirs per directory in the 'manytree' construct. */
     407/** Number of subdirs per directory in the 'manytree' construct. */
    390408static uint32_t     g_cManyTreeSubdirsPerDir    = 16;
    391409/** The depth of the 'manytree' directory tree.  */
     
    400418/** The desired size of the test file we use for I/O. */
    401419static uint64_t     g_cbIoFile                  = _512M;
     420/** Whether to be less strict with non-cache file handle. */
     421static bool         g_fIgnoreNoCache            = false;
    402422
    403423/** The length of g_szDir. */
     
    18601880    uint32_t cbPage = PAGE_SIZE;
    18611881    memset(pbBuf, 0x66, cbBuf);
    1862     RTTESTI_CHECK_RC(RTFileSeek(hFileNoCache, 0, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS);
    1863     for (size_t offBuf = 0; offBuf < cbBuf; )
    1864     {
    1865         uint32_t const cPagesLeft   = (uint32_t)((cbBuf - offBuf) / cbPage);
    1866         uint32_t const cPagesToRead = RTRandU32Ex(1, cPagesLeft);
    1867         size_t const   cbToRead     = cPagesToRead * (size_t)cbPage;
    1868         size_t cbActual = 0;
    1869         RTTESTI_CHECK_RC(RTFileRead(hFileNoCache, &pbBuf[offBuf], cbToRead, &cbActual), VINF_SUCCESS);
    1870         if (cbActual == cbToRead)
    1871             offBuf += cbActual;
    1872         else
    1873         {
    1874             RTTestIFailed("Attempting to read %#zx bytes at %#zx, only got %#x bytes back!\n", cbToRead, offBuf, cbActual);
    1875             if (cbActual)
     1882    if (!g_fIgnoreNoCache || hFileNoCache != NIL_RTFILE)
     1883    {
     1884        RTTESTI_CHECK_RC(RTFileSeek(hFileNoCache, 0, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS);
     1885        for (size_t offBuf = 0; offBuf < cbBuf; )
     1886        {
     1887            uint32_t const cPagesLeft   = (uint32_t)((cbBuf - offBuf) / cbPage);
     1888            uint32_t const cPagesToRead = RTRandU32Ex(1, cPagesLeft);
     1889            size_t const   cbToRead     = cPagesToRead * (size_t)cbPage;
     1890            size_t cbActual = 0;
     1891            RTTESTI_CHECK_RC(RTFileRead(hFileNoCache, &pbBuf[offBuf], cbToRead, &cbActual), VINF_SUCCESS);
     1892            if (cbActual == cbToRead)
    18761893                offBuf += cbActual;
    18771894            else
    18781895            {
    1879                 memset(&pbBuf[offBuf], 0x11, cbPage);
    1880                 offBuf += cbPage;
     1896                RTTestIFailed("Attempting to read %#zx bytes at %#zx, only got %#x bytes back!\n", cbToRead, offBuf, cbActual);
     1897                if (cbActual)
     1898                    offBuf += cbActual;
     1899                else
     1900                {
     1901                    memset(&pbBuf[offBuf], 0x11, cbPage);
     1902                    offBuf += cbPage;
     1903                }
    18811904            }
    18821905        }
    1883     }
    1884     fsPerfCheckReadBuf(__LINE__, 0, pbBuf, cbBuf);
     1906        fsPerfCheckReadBuf(__LINE__, 0, pbBuf, cbBuf);
     1907    }
    18851908
    18861909    /*
     
    20382061    for (unsigned iFile = 0; iFile < RT_ELEMENTS(ahFiles); iFile++, bFiller++)
    20392062    {
     2063        if (g_fIgnoreNoCache && ahFiles[iFile] == NIL_RTFILE)
     2064            continue;
     2065
    20402066        fsPerfFillWriteBuf(0, pbBuf, cbBuf, bFiller);
    20412067        fsPerfCheckReadBuf(__LINE__, 0, pbBuf, cbBuf, bFiller);
     
    21112137#endif
    21122138
    2113     RT_NOREF(hFileNoCache, hFileWriteThru);
    21142139    RTMemPageFree(pbBuf, cbBuf);
    21152140}
     
    22922317                     * Check that all the changes made it thru to the file:
    22932318                     */
    2294                     size_t   cbBuf = _2M;
    2295                     uint8_t *pbBuf = (uint8_t *)RTMemPageAlloc(_2M);
    2296                     if (!pbBuf)
     2319                    if (!g_fIgnoreNoCache || hFileNoCache != NIL_RTFILE)
    22972320                    {
    2298                         cbBuf = _4K;
    2299                         pbBuf = (uint8_t *)RTMemPageAlloc(_2M);
    2300                     }
    2301                     if (pbBuf)
    2302                     {
    2303                         RTTESTI_CHECK_RC(RTFileSeek(hFileNoCache, 0, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS);
    2304                         size_t const cbToCheck = RT_MIN(cFlushes * cbFlush, cbFlushed);
    2305                         unsigned     cErrors   = 0;
    2306                         for (size_t offBuf = 0; cErrors < 32 && offBuf < cbToCheck; offBuf += cbBuf)
     2321                        size_t   cbBuf = _2M;
     2322                        uint8_t *pbBuf = (uint8_t *)RTMemPageAlloc(_2M);
     2323                        if (!pbBuf)
    23072324                        {
    2308                             size_t cbToRead = RT_MIN(cbBuf, cbToCheck - offBuf);
    2309                             RTTESTI_CHECK_RC(RTFileRead(hFileNoCache, pbBuf, cbToRead, NULL), VINF_SUCCESS);
    2310 
    2311                             for (size_t offFlush = 0; offFlush < cbToRead; offFlush += PAGE_SIZE)
    2312                                 if (*(size_t volatile *)&pbBuf[offFlush + 8] != cbFlush)
    2313                                 {
    2314                                     RTTestIFailed("Flush issue at offset #%zx: %#zx, expected %#zx (cbFlush=%#zx)",
    2315                                                   offBuf, *(size_t volatile *)&pbBuf[offFlush + 8], cbFlush, cbFlush);
    2316                                     if (++cErrors > 32)
    2317                                         break;
    2318                                 }
     2325                            cbBuf = _4K;
     2326                            pbBuf = (uint8_t *)RTMemPageAlloc(_2M);
    23192327                        }
    2320                         RTMemPageFree(pbBuf, cbBuf);
     2328                        if (pbBuf)
     2329                        {
     2330                            RTTESTI_CHECK_RC(RTFileSeek(hFileNoCache, 0, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS);
     2331                            size_t const cbToCheck = RT_MIN(cFlushes * cbFlush, cbFlushed);
     2332                            unsigned     cErrors   = 0;
     2333                            for (size_t offBuf = 0; cErrors < 32 && offBuf < cbToCheck; offBuf += cbBuf)
     2334                            {
     2335                                size_t cbToRead = RT_MIN(cbBuf, cbToCheck - offBuf);
     2336                                RTTESTI_CHECK_RC(RTFileRead(hFileNoCache, pbBuf, cbToRead, NULL), VINF_SUCCESS);
     2337
     2338                                for (size_t offFlush = 0; offFlush < cbToRead; offFlush += PAGE_SIZE)
     2339                                    if (*(size_t volatile *)&pbBuf[offFlush + 8] != cbFlush)
     2340                                    {
     2341                                        RTTestIFailed("Flush issue at offset #%zx: %#zx, expected %#zx (cbFlush=%#zx)",
     2342                                                      offBuf, *(size_t volatile *)&pbBuf[offFlush + 8], cbFlush, cbFlush);
     2343                                        if (++cErrors > 32)
     2344                                            break;
     2345                                    }
     2346                            }
     2347                            RTMemPageFree(pbBuf, cbBuf);
     2348                        }
    23212349                    }
    23222350                }
     
    23832411                                     RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE | RTFILE_O_READWRITE), VINF_SUCCESS);
    23842412    RTFILE hFileNoCache;
    2385     RTTESTI_CHECK_RC_RETV(RTFileOpen(&hFileNoCache, g_szDir,
    2386                                      RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_READWRITE | RTFILE_O_NO_CACHE),
    2387                           VINF_SUCCESS);
     2413    if (!g_fIgnoreNoCache)
     2414        RTTESTI_CHECK_RC_RETV(RTFileOpen(&hFileNoCache, g_szDir,
     2415                                         RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_READWRITE | RTFILE_O_NO_CACHE),
     2416                              VINF_SUCCESS);
     2417    else
     2418    {
     2419        int rc = RTFileOpen(&hFileNoCache, g_szDir, RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_READWRITE | RTFILE_O_NO_CACHE);
     2420        if (RT_FAILURE(rc))
     2421        {
     2422            RTTestIPrintf(RTTESTLVL_ALWAYS, "Unable to open I/O file with non-cache flag (%Rrc), skipping related tests.\n", rc);
     2423            hFileNoCache = NIL_RTFILE;
     2424        }
     2425    }
    23882426    RTFILE hFileWriteThru;
    23892427    RTTESTI_CHECK_RC_RETV(RTFileOpen(&hFileWriteThru, g_szDir,
     
    24222460    RTTESTI_CHECK_RC(RTFileSetSize(hFile1, 0), VINF_SUCCESS);
    24232461    RTTESTI_CHECK_RC(RTFileClose(hFile1), VINF_SUCCESS);
    2424     RTTESTI_CHECK_RC(RTFileClose(hFileNoCache), VINF_SUCCESS);
     2462    if (hFileNoCache != NIL_RTFILE || !g_fIgnoreNoCache)
     2463        RTTESTI_CHECK_RC(RTFileClose(hFileNoCache), VINF_SUCCESS);
    24252464    RTTESTI_CHECK_RC(RTFileClose(hFileWriteThru), VINF_SUCCESS);
    24262465    RTTESTI_CHECK_RC(RTFileDelete(g_szDir), VINF_SUCCESS);
     
    24282467
    24292468
     2469/**
     2470 * Display the usage to @a pStrm.
     2471 */
    24302472static void Usage(PRTSTREAM pStrm)
    24312473{
     
    24422484        switch (g_aCmdOptions[i].iShort)
    24432485        {
    2444             case 'd':   pszHelp = "The directory to use for testing.  Default: CWD/fstestdir"; break;
    2445             case 'e':   pszHelp = "Enables all tests.   Default: -e"; break;
    2446             case 'z':   pszHelp = "Disables all tests.  Default: -e"; break;
    2447             case 's':   pszHelp = "Set benchmark duration in seconds.  Default: 10 sec"; break;
    2448             case 'm':   pszHelp = "Set benchmark duration in milliseconds.  Default: 10000 ms"; break;
    2449             case 'v':   pszHelp = "More verbose execution."; break;
    2450             case 'q':   pszHelp = "Quiet execution."; break;
    2451             case 'h':   pszHelp = "Displays this help and exit"; break;
    2452             case 'V':   pszHelp = "Displays the program revision"; break;
    2453             case kCmdOpt_ShowDuration:      pszHelp =  "Show duration of profile runs. default: --no-show-duration"; break;
    2454             case kCmdOpt_NoShowDuration:    pszHelp =  "Hide duration of profile runs. default: --no-show-duration"; break;
    2455             case kCmdOpt_ShowIterations:    pszHelp =  "Show iteration count for profile runs. default: --no-show-iterations"; break;
    2456             case kCmdOpt_NoShowIterations:  pszHelp =  "Hide iteration count for profile runs. default: --no-show-iterations"; break;
     2486            case 'd':                           pszHelp = "The directory to use for testing.            default: CWD/fstestdir"; break;
     2487            case 'e':                           pszHelp = "Enables all tests.                           default: -e"; break;
     2488            case 'z':                           pszHelp = "Disables all tests.                          default: -e"; break;
     2489            case 's':                           pszHelp = "Set benchmark duration in seconds.           default: 10 sec"; break;
     2490            case 'm':                           pszHelp = "Set benchmark duration in milliseconds.      default: 10000 ms"; break;
     2491            case 'v':                           pszHelp = "More verbose execution."; break;
     2492            case 'q':                           pszHelp = "Quiet execution."; break;
     2493            case 'h':                           pszHelp = "Displays this help and exit"; break;
     2494            case 'V':                           pszHelp = "Displays the program revision"; break;
     2495            case kCmdOpt_ShowDuration:          pszHelp = "Show duration of profile runs.               default: --no-show-duration"; break;
     2496            case kCmdOpt_NoShowDuration:        pszHelp = "Hide duration of profile runs.               default: --no-show-duration"; break;
     2497            case kCmdOpt_ShowIterations:        pszHelp = "Show iteration count for profile runs.       default: --no-show-iterations"; break;
     2498            case kCmdOpt_NoShowIterations:      pszHelp = "Hide iteration count for profile runs.       default: --no-show-iterations"; break;
     2499            case kCmdOpt_ManyFiles:             pszHelp = "Count of files in big test dir.              default: --many-files 10000"; break;
     2500            case kCmdOpt_NoManyFiles:           pszHelp = "Skip big test dir with many files.           default: --many-files 10000"; break;
     2501            case kCmdOpt_ManyTreeFilesPerDir:   pszHelp = "Count of files per directory in test tree.   default: 640"; break;
     2502            case kCmdOpt_ManyTreeSubdirsPerDir: pszHelp = "Count of subdirs per directory in test tree. default: 16"; break;
     2503            case kCmdOpt_ManyTreeDepth:         pszHelp = "Depth of test tree (not counting root).      default: 1"; break;
     2504            case kCmdOpt_IgnoreNoCache:         pszHelp = "Ignore error wrt no-cache handle.            default: --no-ignore-no-cache"; break;
     2505            case kCmdOpt_NoIgnoreNoCache:       pszHelp = "Do not ignore error wrt no-cache handle.     default: --no-ignore-no-cache"; break;
     2506            case kCmdOpt_IoFileSize:            pszHelp = "Size of file used for I/O tests.             default: 512 MB"; break;
     2507            case kCmdOpt_SetBlockSize:          pszHelp = "Sets single I/O block size (in bytes)."; break;
     2508            case kCmdOpt_AddBlockSize:          pszHelp = "Adds an I/O block size (in bytes)."; break;
    24572509            default:
    24582510                if (g_aCmdOptions[i].iShort >= kCmdOpt_First)
     
    24722524            char szOpt[64];
    24732525            RTStrPrintf(szOpt, sizeof(szOpt), "%s, -%c", g_aCmdOptions[i].pszLong, g_aCmdOptions[i].iShort);
    2474             RTStrmPrintf(pStrm, "  %-20s%s\n", szOpt, pszHelp);
     2526            RTStrmPrintf(pStrm, "  %-19s %s\n", szOpt, pszHelp);
    24752527        }
    24762528        else
    2477             RTStrmPrintf(pStrm, "  %-20s%s\n", g_aCmdOptions[i].pszLong, pszHelp);
    2478     }
     2529            RTStrmPrintf(pStrm, "  %-19s %s\n", g_aCmdOptions[i].pszLong, pszHelp);
     2530    }
     2531}
     2532
     2533
     2534static uint32_t fsPerfCalcManyTreeFiles(void)
     2535{
     2536    uint32_t cDirs = 1;
     2537    for (uint32_t i = 0, cDirsAtLevel = 1; i < g_cManyTreeDepth; i++)
     2538    {
     2539        cDirs += cDirsAtLevel * g_cManyTreeSubdirsPerDir;
     2540        cDirsAtLevel *= g_cManyTreeSubdirsPerDir;
     2541    }
     2542    return g_cManyTreeFilesPerDir * cDirs;
    24792543}
    24802544
     
    25862650            case RT_CONCAT(kCmdOpt_,a_Stem):   RT_CONCAT(g_f,a_Stem) = true; break; \
    25872651            case RT_CONCAT(kCmdOpt_No,a_Stem): RT_CONCAT(g_f,a_Stem) = false; break
    2588             CASE_OPT(ManyFiles);
    25892652            CASE_OPT(Open);
    25902653            CASE_OPT(FStat);
     
    26052668            CASE_OPT(FSync);
    26062669            CASE_OPT(MMap);
     2670            CASE_OPT(IgnoreNoCache);
    26072671
    26082672            CASE_OPT(ShowDuration);
    26092673            CASE_OPT(ShowIterations);
    26102674#undef CASE_OPT
     2675
     2676            case kCmdOpt_ManyFiles:
     2677                g_fManyFiles = ValueUnion.u32 > 0;
     2678                g_cManyFiles = ValueUnion.u32;
     2679                break;
     2680
     2681            case kCmdOpt_NoManyFiles:
     2682                g_fManyFiles = false;
     2683                break;
     2684
     2685            case kCmdOpt_ManyTreeFilesPerDir:
     2686                if (ValueUnion.u32 > 0 && ValueUnion.u32 <= _64M)
     2687                {
     2688                    g_cManyTreeFilesPerDir = ValueUnion.u32;
     2689                    g_cManyTreeFiles = fsPerfCalcManyTreeFiles();
     2690                    break;
     2691                }
     2692                RTTestFailed(g_hTest, "Out of range --files-per-dir value: %u (%#x)\n", ValueUnion.u32, ValueUnion.u32);
     2693                return RTTestSummaryAndDestroy(g_hTest);
     2694
     2695            case kCmdOpt_ManyTreeSubdirsPerDir:
     2696                if (ValueUnion.u32 > 0 && ValueUnion.u32 <= 1024)
     2697                {
     2698                    g_cManyTreeSubdirsPerDir = ValueUnion.u32;
     2699                    g_cManyTreeFiles = fsPerfCalcManyTreeFiles();
     2700                    break;
     2701                }
     2702                RTTestFailed(g_hTest, "Out of range --subdirs-per-dir value: %u (%#x)\n", ValueUnion.u32, ValueUnion.u32);
     2703                return RTTestSummaryAndDestroy(g_hTest);
     2704
     2705            case kCmdOpt_ManyTreeDepth:
     2706                if (ValueUnion.u32 <= 8)
     2707                {
     2708                    g_cManyTreeDepth = ValueUnion.u32;
     2709                    g_cManyTreeFiles = fsPerfCalcManyTreeFiles();
     2710                    break;
     2711                }
     2712                RTTestFailed(g_hTest, "Out of range --tree-depth value: %u (%#x)\n", ValueUnion.u32, ValueUnion.u32);
     2713                return RTTestSummaryAndDestroy(g_hTest);
     2714
     2715            case kCmdOpt_IoFileSize:
     2716                if (ValueUnion.u64 == 0)
     2717                    g_cbIoFile = _512M;
     2718                else
     2719                    g_cbIoFile = ValueUnion.u64;
     2720                break;
     2721
     2722            case kCmdOpt_SetBlockSize:
     2723                if (ValueUnion.u32 > 0)
     2724                {
     2725                    g_cIoBlocks = 1;
     2726                    g_acbIoBlocks[0] = ValueUnion.u32;
     2727                }
     2728                else
     2729                {
     2730                    RTTestFailed(g_hTest, "Invalid I/O block size: %u (%#x)\n", ValueUnion.u32, ValueUnion.u32);
     2731                    return RTTestSummaryAndDestroy(g_hTest);
     2732                }
     2733                break;
     2734
     2735            case kCmdOpt_AddBlockSize:
     2736                if (g_cIoBlocks >= RT_ELEMENTS(g_acbIoBlocks))
     2737                    RTTestFailed(g_hTest, "Too many I/O block sizes: max %u\n", RT_ELEMENTS(g_acbIoBlocks));
     2738                else if (ValueUnion.u32 == 0)
     2739                    RTTestFailed(g_hTest, "Invalid I/O block size: %u (%#x)\n", ValueUnion.u32, ValueUnion.u32);
     2740                else
     2741                {
     2742                    g_acbIoBlocks[g_cIoBlocks++] = ValueUnion.u32;
     2743                    break;
     2744                }
     2745                return RTTestSummaryAndDestroy(g_hTest);
    26112746
    26122747            case 'q':
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