From 592fa1feeaa2d95c70568835075c8e966fc0026d Mon Sep 17 00:00:00 2001 From: nikita Date: Wed, 24 Aug 2005 19:27:08 +0000 Subject: [PATCH] add new testing proglet random-reads.c to benchmark bug 6252 fix. random-reads.c randomly reads chunks of given size from the given file. See "random-reads -h" for (ridiculously incomplete) help. --- lustre/tests/random-reads.c | 186 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 lustre/tests/random-reads.c diff --git a/lustre/tests/random-reads.c b/lustre/tests/random-reads.c new file mode 100644 index 0000000..1070835 --- /dev/null +++ b/lustre/tests/random-reads.c @@ -0,0 +1,186 @@ +/* + * Lustre Random Reads test + * + * Copyright (c) 2005 Cluster File Systems, Inc. + * + * Author: Nikita Danilov + * + * This file is part of Lustre, http://www.lustre.org. + * + * Lustre is free software; you can redistribute it and/or modify it under the + * terms of version 2 of the GNU General Public License as published by the + * Free Software Foundation. + * + * Lustre is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along + * with Lustre; if not, write to the Free Software Foundation, Inc., 675 Mass + * Ave, Cambridge, MA 02139, USA. + */ + +#define _XOPEN_SOURCE 500 /* for pread(2) */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static void usage(void) +{ + printf("random-reads: read random chunks of a file.\n"); + printf("Usage:\n\n"); + printf("random-reads -f -s -b [-v] [-h] [-C] [-S ] [-n ] [-w ]\n"); +} + +enum { + BSIZE_DEFAULT = 16 * 4096 +}; + +#define LOG(level, ...) \ +({ \ + if ((level) <= verbosity) \ + fprintf(stderr, __VA_ARGS__); \ +}) + +enum { + LOG_CRIT, + LOG_WARN, + LOG_INFO, + LOG_DEBUG +}; + +enum { + RR_OK, + RR_PARSE, + RR_SET, + RR_MALLOC, + RR_OPEN, + RR_PRECLEAN, + RR_READ +}; + +int main(int argc, char **argv) +{ + int verbosity = LOG_CRIT; + char *fname = NULL; + loff_t size = 0; + size_t bsize = 0; + int preclean = 0; + int width = 10; + unsigned int seed = 0; + unsigned long iterations = 0; + + int opt; + int fd; + unsigned long nblocks; + unsigned long i; + ssize_t ret; + + struct timeval start; + struct timeval stop; + + double usecs; + + char *buf; + + do { + opt = getopt(argc, argv, "f:s:b:vhCS:n:w:"); + switch (opt) { + case -1: + break; + default: + LOG(LOG_CRIT, "Unable to parse command line.\n"); + case 'h': + usage(); + return RR_PARSE; + case 'v': + verbosity ++; + break; + case 'f': + fname = strdup(optarg); + break; + case 's': + size = atoll(optarg); + break; + case 'b': + bsize = atol(optarg); + break; + case 'C': + preclean = 1; + break; + case 'S': + seed = atol(optarg); + break; + case 'n': + iterations = atoll(optarg); + break; + case 'w': + width = atoi(optarg); + break; + } + } while (opt != -1); + + if (fname == NULL || size == 0 || bsize == 0) { + usage(); + return RR_SET; + } + + nblocks = size / bsize; + buf = malloc(bsize); + if (buf == NULL) { + LOG(LOG_CRIT, "malloc(%i) failure: %m\n", bsize); + return RR_MALLOC; + } + + fd = open(fname, (preclean ? O_RDWR : O_RDONLY) | O_CREAT, 0700); + if (fd == -1) { + LOG(LOG_CRIT, "malloc(\"%s\") failure: %m\n", fname); + return RR_OPEN; + } + if (preclean) { + loff_t towrite; + size_t count; + + LOG(LOG_INFO, "precleaning"); + for (i = 0, towrite = size; towrite > 0; towrite -= ret) { + count = bsize < towrite ? bsize : towrite; + memset(buf, bsize, seed + i++); + ret = write(fd, buf, count); + if (ret < 0) { + LOG(LOG_CRIT, "write() failure: %m\n"); + return RR_PRECLEAN; + } + } + } + if (seed != 0) + srand(seed); + gettimeofday(&start, NULL); + for (i = 0; !iterations || i < iterations; i ++) { + unsigned long block_nr; + + block_nr = (int) ((double)nblocks*rand()/(RAND_MAX+1.0)); + if (i % width == 0) + LOG(LOG_INFO, "\n%9lu: ", i); + LOG(LOG_INFO, "%7lu ", block_nr); + ret = pread(fd, buf, bsize, block_nr * bsize); + if (ret != bsize) { + LOG(LOG_CRIT, "pread(...%zi, %li) got: %zi, %m\n", + bsize, block_nr * bsize, ret); + return RR_READ; + } + } + gettimeofday(&stop, NULL); + usecs = (stop.tv_sec - start.tv_sec) * 1000000. + + stop.tv_usec - start.tv_usec; + printf("\n%f\n", usecs / 1000000.); + return RR_OK; +} -- 1.8.3.1