From 5825dbae3598443a1b146647ad3b5dc85ccb29b5 Mon Sep 17 00:00:00 2001 From: "Julian M. Kunkel" Date: Tue, 1 Dec 2020 13:52:29 +0000 Subject: [PATCH] Provide new option randomPrefill for random (-z access only) that prefill the file with the specified blocksize, e.g., 2m. See issue #270. This option works so far only without stonewalling! --- src/ior.c | 49 +++++++++++++++++++++++++++++++++++---------- src/ior.h | 3 ++- src/parse_options.c | 1 + 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/ior.c b/src/ior.c index 3aaf195..a6dd412 100755 --- a/src/ior.c +++ b/src/ior.c @@ -1588,7 +1588,10 @@ static void ValidateTests(IOR_param_t * test) ERR("block size must not be smaller than transfer size"); if (test->randomOffset && test->blockSize == test->transferSize) ERR("IOR will randomize access within a block and repeats the same pattern for all segments, therefore choose blocksize > transferSize"); - + if (! test->randomOffset && test->randomPrefillBlocksize) + ERR("Setting the randomPrefill option without using random is not useful"); + if (test->randomPrefillBlocksize && (test->blockSize % test->randomPrefillBlocksize != 0)) + ERR("The randomPrefill option must divide the blockSize"); /* specific APIs */ if ((strcasecmp(test->api, "MPIIO") == 0) && (test->blockSize < sizeof(IOR_size_t) @@ -1732,14 +1735,10 @@ IOR_offset_t *GetOffsetArrayRandom(IOR_param_t * test, int pretendRank, IOR_offs return (offsetArray); } -static IOR_offset_t WriteOrReadSingle(IOR_offset_t offset, int pretendRank, - IOR_offset_t * transferCount, int * errors, IOR_param_t * test, aiori_fd_t * fd, IOR_io_buffers* ioBuffers, int access){ +static IOR_offset_t WriteOrReadSingle(IOR_offset_t offset, int pretendRank, IOR_offset_t transfer, IOR_offset_t * transferCount, int * errors, IOR_param_t * test, aiori_fd_t * fd, IOR_io_buffers* ioBuffers, int access){ IOR_offset_t amtXferred = 0; - IOR_offset_t transfer; void *buffer = ioBuffers->buffer; - - transfer = test->transferSize; if (access == WRITE) { /* fills each transfer with a unique pattern * containing the offset into the file */ @@ -1804,9 +1803,6 @@ static IOR_offset_t WriteOrRead(IOR_param_t *test, IOR_results_t *results, // offsetArray = GetOffsetArraySequential(test, pretendRank); - startForStonewall = GetTimeStamp(); - hitStonewall = 0; - IOR_offset_t offsets; IOR_offset_t * offsets_rnd; if (test->randomOffset) { @@ -1815,7 +1811,38 @@ static IOR_offset_t WriteOrRead(IOR_param_t *test, IOR_results_t *results, offsets = (test->blockSize / test->transferSize); } + // start timer after random offset was generated + startForStonewall = GetTimeStamp(); + hitStonewall = 0; + + if(test->randomPrefillBlocksize && test->deadlineForStonewalling == 0){ + // prefill the whole file already with an invalid pattern + int offsets = test->blockSize / test->randomPrefillBlocksize; + void * oldBuffer = ioBuffers->buffer; + ioBuffers->buffer = aligned_buffer_alloc(test->randomPrefillBlocksize); + // store invalid data into the buffer + memset(ioBuffers->buffer, -1, test->randomPrefillBlocksize); + for (i = 0; i < test->segmentCount; i++){ + for (j = 0; j < offsets; j++) { + IOR_offset_t offset = j * test->randomPrefillBlocksize; + if (test->filePerProc) { + offset += i * test->blockSize; + } else { + offset += (i * test->numTasks * test->blockSize) + (pretendRank * test->blockSize); + } + WriteOrReadSingle(offset, pretendRank, test->randomPrefillBlocksize, & transferCount, & errors, test, fd, ioBuffers, access); + } + } + aligned_buffer_free(ioBuffers->buffer); + ioBuffers->buffer = oldBuffer; + } + for (i = 0; i < test->segmentCount && !hitStonewall; i++) { + if(test->randomPrefillBlocksize && test->deadlineForStonewalling != 0){ + // prefill the whole segment with data + // TODO + ERR("Not supported, yet"); + } for (j = 0; j < offsets && !hitStonewall ; j++) { IOR_offset_t offset; if (test->randomOffset) { @@ -1832,7 +1859,7 @@ static IOR_offset_t WriteOrRead(IOR_param_t *test, IOR_results_t *results, offset += (i * test->numTasks * test->blockSize) + (pretendRank * test->blockSize); } } - dataMoved += WriteOrReadSingle(offset, pretendRank, & transferCount, & errors, test, fd, ioBuffers, access); + dataMoved += WriteOrReadSingle(offset, pretendRank, test->transferSize, & transferCount, & errors, test, fd, ioBuffers, access); pairCnt++; hitStonewall = ((test->deadlineForStonewalling != 0 @@ -1888,7 +1915,7 @@ static IOR_offset_t WriteOrRead(IOR_param_t *test, IOR_results_t *results, offset += (i * test->numTasks * test->blockSize) + (pretendRank * test->blockSize); } } - dataMoved += WriteOrReadSingle(offset, pretendRank, & transferCount, & errors, test, fd, ioBuffers, access); + dataMoved += WriteOrReadSingle(offset, pretendRank, test->transferSize, & transferCount, & errors, test, fd, ioBuffers, access); pairCnt++; } } diff --git a/src/ior.h b/src/ior.h index 843884d..33034c9 100755 --- a/src/ior.h +++ b/src/ior.h @@ -127,6 +127,7 @@ typedef struct IOR_offset_t blockSize; /* contiguous bytes to write per task */ IOR_offset_t transferSize; /* size of transfer in bytes */ IOR_offset_t expectedAggFileSize; /* calculated aggregate file size */ + IOR_offset_t randomPrefillBlocksize; /* prefill option for random IO, the amount of data used for prefill */ int summary_every_test; /* flag to print summary every test, not just at end */ int uniqueDir; /* use unique directory for each fpp */ @@ -168,7 +169,7 @@ typedef struct int hdfs_block_size; /* internal blk-size. (0 gets default) */ char* URI; /* "path" to target object */ - + /* RADOS variables */ rados_t rados_cluster; /* RADOS cluster handle */ rados_ioctx_t rados_ioctx; /* I/O context for our pool in the RADOS cluster */ diff --git a/src/parse_options.c b/src/parse_options.c index 12f8e0c..1a2ad7e 100755 --- a/src/parse_options.c +++ b/src/parse_options.c @@ -433,6 +433,7 @@ option_help * createGlobalOptions(IOR_param_t * params){ {'y', NULL, "dualMount -- use dual mount points for a filesystem", OPTION_FLAG, 'd', & params->dualMount}, {'Y', NULL, "fsyncPerWrite -- perform sync operation after every write operation", OPTION_FLAG, 'd', & params->fsyncPerWrite}, {'z', NULL, "randomOffset -- access is to random, not sequential, offsets within a file", OPTION_FLAG, 'd', & params->randomOffset}, + {0, "randomPrefill", "For random -z access only: Prefill the file with this blocksize, e.g., 2m", OPTION_OPTIONAL_ARGUMENT, 'l', & params->randomPrefillBlocksize}, {0, "random-offset-seed", "The seed for -z", OPTION_OPTIONAL_ARGUMENT, 'd', & params->randomSeed}, {'Z', NULL, "reorderTasksRandom -- changes task ordering to random ordering for readback", OPTION_FLAG, 'd', & params->reorderTasksRandom}, {0, "warningAsErrors", "Any warning should lead to an error.", OPTION_FLAG, 'd', & params->warningAsErrors},