2 * Lustre Random Reads test
4 * Copyright (c) 2005 Cluster File Systems, Inc.
6 * Author: Nikita Danilov <nikita@clusterfs.com>
8 * This file is part of Lustre, http://www.lustre.org.
10 * Lustre is free software; you can redistribute it and/or modify it under the
11 * terms of version 2 of the GNU General Public License as published by the
12 * Free Software Foundation.
14 * Lustre is distributed in the hope that it will be useful, but WITHOUT ANY
15 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19 * You should have received a copy of the GNU General Public License along
20 * with Lustre; if not, write to the Free Software Foundation, Inc., 675 Mass
21 * Ave, Cambridge, MA 02139, USA.
24 #define _XOPEN_SOURCE 500 /* for pread(2) */
34 #include <sys/types.h>
37 long long atoll(const char *nptr);
39 static void usage(void)
41 printf("random-reads: read random chunks of a file.\n");
43 printf("random-reads -f <filename> -s <filesize> -b <buffersize> -a <adjacent reads> [-v] [-h] [-C] [-S <seed>] [-n <iterations>] [-w <width>] [-t <timelimit>]\n");
47 BSIZE_DEFAULT = 16 * 4096
50 #define LOG(level, ...) \
52 if ((level) <= verbosity) \
53 fprintf(stderr, __VA_ARGS__); \
73 int main(int argc, char **argv)
75 int verbosity = LOG_CRIT;
82 unsigned int seed = 0;
83 unsigned long iterations = 0;
84 unsigned long timelimit = 24 * 3600;
88 unsigned long nblocks;
100 opt = getopt(argc, argv, "f:s:b:va:hCS:n:t:w:");
105 LOG(LOG_CRIT, "Unable to parse command line.\n");
113 fname = strdup(optarg);
116 size = atoll(optarg);
119 bsize = atol(optarg);
131 iterations = atoll(optarg);
134 timelimit = atoll(optarg);
137 width = atoi(optarg);
142 if (fname == NULL || size == 0 || bsize == 0 || ad <= 0) {
148 nblocks = size / bsize;
151 LOG(LOG_CRIT, "malloc(%lu) failure: %s\n", (long)bsize,
156 fd = open(fname, (preclean ? O_RDWR : O_RDONLY) | O_CREAT, 0700);
158 LOG(LOG_CRIT, "malloc(\"%s\") failure: %s\n", fname,
166 LOG(LOG_INFO, "precleaning");
167 for (i = 0, towrite = size; towrite > 0; towrite -= ret) {
168 count = bsize < towrite ? bsize : towrite;
169 memset(buf, bsize, seed + i++);
170 ret = write(fd, buf, count);
172 LOG(LOG_CRIT, "write() failure: %s\n",
180 gettimeofday(&start, NULL);
181 timelimit += start.tv_sec;
182 for (i = 0; !iterations || i < iterations; i ++) {
183 unsigned long block_nr;
186 block_nr = (int) ((double)nblocks*rand()/(RAND_MAX+1.0));
188 LOG(LOG_INFO, "\n%9lu: ", i);
189 LOG(LOG_INFO, "%7lu ", block_nr);
190 for (j = 0; j < ad; j++) {
191 ret = pread(fd, buf, bsize, (block_nr + j) * bsize);
194 "pread(...%zi, %li) got: %zi, %s\n", bsize,
195 block_nr * bsize, ret, strerror(errno));
199 gettimeofday(&stop, NULL);
200 if (stop.tv_sec > timelimit)
203 usecs = (stop.tv_sec - start.tv_sec) * 1000000. +
204 stop.tv_usec - start.tv_usec;
205 printf("\n%fs, %gMB/s\n", usecs / 1000000.,
206 (double)bsize * ad * i / usecs);