-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
* 2003, Copyright, Hewlett-Packard Development Compnay, LP.
*
* Developed under the sponsorship of the U.S. Government
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright (c) 2012, 2015, Intel Corporation.
*/
#include <stdio.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <dirent.h>
+#include <sys/xattr.h>
#include "mpi.h"
/* lustre */
-#include <liblustre.h>
-#include <lustre/liblustreapi.h> /* for O_LOV_DELAY_CREATE */
+#include <lustre/lustreapi.h> /* for O_LOV_DELAY_CREATE */
#define CHECK_COUNT 10000
#define DISPLAY_COUNT (CHECK_COUNT * 10)
#define DISPLAY_TIME 100
enum {
- CREATE = 'c',
- LOOKUP = 'l',
- MKNOD = 'm',
- OPEN = 'o',
- STAT = 's',
- UNLINK = 'u',
- BEGIN = 'b',
- ITERS = 'i',
- TIME = 't',
- DIRFMT = 'd',
- NDIRS = 'D',
- FILEFMT = 'f',
- NFILES = 'F',
- NOEXCL = 'X',
- STRIPES = 'S',
- SEED = 'r',
- SEEDFILE = 'R',
- RANDOM = 'A',
- READDIR = 'B',
- RECREATE = 'C',
- IGNORE = 'E',
- VERBOSE = 'V',
- DEBUG = 'v',
- HELP = 'h',
+ CREATE = 'c',
+ LOOKUP = 'l',
+ MKNOD = 'm',
+ OPEN = 'o',
+ STAT = 's',
+ UNLINK = 'u',
+ BEGIN = 'b',
+ ITERS = 'i',
+ TIME = 't',
+ DIRFMT = 'd',
+ NDIRS = 'D',
+ FILEFMT = 'f',
+ NFILES = 'F',
+ NOEXCL = 'X',
+ STRIPES = 'S',
+ SEED = 'r',
+ SEEDFILE = 'R',
+ RANDOM = 'A',
+ READDIR = 'B',
+ RECREATE = 'C',
+ SETXATTR = 'x',
+ SMALLWRITE = 'w',
+ IGNORE = 'E',
+ VERBOSE = 'V',
+ DEBUG = 'v',
+ HELP = 'h',
+ MNT = 'M',
+ MNTCOUNT = 'N',
+ MDTCOUNT = 'T',
};
struct option longOpts[] = {
- {"create", 0, NULL, CREATE },
- {"lookup", 0, NULL, LOOKUP },
- {"mknod", 0, NULL, MKNOD },
- {"open", 0, NULL, OPEN },
- {"stat", 0, NULL, STAT },
- {"unlink", 0, NULL, UNLINK },
- {"begin", 1, NULL, BEGIN },
- {"iters", 1, NULL, ITERS },
- {"time", 1, NULL, TIME }, /* seconds */
- {"dirfmt", 1, NULL, DIRFMT },
- {"ndirs", 1, NULL, NDIRS },
- {"filefmt", 1, NULL, FILEFMT },
- {"nfiles", 1, NULL, NFILES },
- {"noexcl", 0, NULL, NOEXCL },
- {"stripes", 1, NULL, STRIPES },
- {"seed", 1, NULL, SEED },
- {"seedfile", 1, NULL, SEEDFILE },
- {"random_order", 0, NULL, RANDOM },
- {"readdir_order", 0, NULL, READDIR },
- {"recreate", 0, NULL, RECREATE },
- {"ignore", 0, NULL, IGNORE },
- {"verbose", 0, NULL, VERBOSE },
- {"debug", 0, NULL, DEBUG },
- {"help", 0, NULL, HELP },
- { 0, 0, NULL, 0 }
+ {"create", 0, NULL, CREATE },
+ {"lookup", 0, NULL, LOOKUP },
+ {"mknod", 0, NULL, MKNOD },
+ {"open", 0, NULL, OPEN },
+ {"stat", 0, NULL, STAT },
+ {"unlink", 0, NULL, UNLINK },
+ {"begin", 1, NULL, BEGIN },
+ {"iters", 1, NULL, ITERS },
+ {"time", 1, NULL, TIME }, /* seconds */
+ {"dirfmt", 1, NULL, DIRFMT },
+ {"ndirs", 1, NULL, NDIRS },
+ {"filefmt", 1, NULL, FILEFMT },
+ {"nfiles", 1, NULL, NFILES },
+ {"noexcl", 0, NULL, NOEXCL },
+ {"stripes", 1, NULL, STRIPES },
+ {"seed", 1, NULL, SEED },
+ {"seedfile", 1, NULL, SEEDFILE },
+ {"random_order", 0, NULL, RANDOM },
+ {"readdir_order", 0, NULL, READDIR },
+ {"recreate", 0, NULL, RECREATE },
+ {"setxattr", 0, NULL, SETXATTR },
+ {"smallwrite", 0, NULL, SMALLWRITE },
+ {"ignore", 0, NULL, IGNORE },
+ {"verbose", 0, NULL, VERBOSE },
+ {"debug", 0, NULL, DEBUG },
+ {"help", 0, NULL, HELP },
+ {"mdtcount", 1, NULL, MDTCOUNT },
+ {"mntcount", 1, NULL, MNTCOUNT },
+ {"mntfmt", 1, NULL, MNT },
+ { 0, 0, NULL, 0 }
};
int foo1, foo2;
int nfiles;
char filefmt[PATH_MAX];
char filename[PATH_MAX];
+char path[PATH_MAX];
int stripes = -1;
int begin;
int beginsave;
int verbose;
int debug;
struct stat statbuf;
+bool with_xattr;
+char xattrname[] = "user.mdsrate";
+char xattrbuf[4096];
+/* max xattr name + value length is block size, use 4000 here to avoid ENOSPC */
+int xattrlen = 4000;
+bool smallwrite;
+int mnt_count = -1;
+int mdt_count = 1;
+char *mntfmt;
#define dmesg if (debug) printf
#define DISPLAY_PROGRESS() { \
- if ((++nops % CHECK_COUNT) == 0 && verbose) { \
- curTime = time(0); \
+ if (verbose && (nops % CHECK_COUNT == 0)) { \
+ curTime = MPI_Wtime(); \
interval = curTime - lastTime; \
if (interval > DISPLAY_TIME || nops % DISPLAY_COUNT == 0) { \
- rate = (float)(nops - lastOps); \
- if (interval > 1) \
- rate /= (float)interval; \
- printf("Rank %d: %.2f %ss/sec %lu secs " \
- "(total: %d %ss %lu secs)\n", \
+ rate = (double)(nops - lastOps)/interval; \
+ printf("Rank %d: %.2f %ss/sec %.2f secs " \
+ "(total: %d %ss %.2f secs)\n", \
myrank, rate, cmd, interval, \
nops, cmd, curTime - startTime); \
lastOps = nops; \
}
char *usage_msg = "usage: %s\n"
- " { --create [ --noexcl ] | --lookup | --mknod |\n"
- " --open | --stat | --unlink [ --recreate ] [ --ignore ] }\n"
- " [ --help ] [ --verbose ] [ --debug ]\n"
- " { [ --begin <num> ] --nfiles <num> }\n"
- " [ --iters <num> ] [ --time <secs> ]\n"
- " [ --dirfmt <str> ] [ --ndirs <num> ]\n"
- " [ --filefmt <str> ] [ --stripes <num> ]\n"
- " [ --random_order [--seed <num> | --seedfile <file>] ]\n"
- " [ --readdir_order ]\n";
+ " { --create [ --noexcl | --setxattr | --smallwrite ] |\n"
+ " --lookup | --mknod [ --setxattr ] | --open |\n"
+ " --stat | --unlink [ --recreate ] [ --ignore ] |\n"
+ " --setxattr }\n"
+ " [ --help ] [ --verbose ] [ --debug ]\n"
+ " { [ --begin <num> ] --nfiles <num> }\n"
+ " [ --iters <num> ] [ --time <secs> ]\n"
+ " [ --dirfmt <str> ] [ --ndirs <num> ]\n"
+ " [ --filefmt <str> ] [ --stripes <num> ]\n"
+ " [ --random_order [--seed <num> | --seedfile <file>] ]\n"
+ " [ --readdir_order ] [ --mntfmt <str> ]\n"
+ " [ --mntcount <num> ] [ --mdtcount <num> ]\n"
+ " [ --setxattr ] }\n";
static void
usage(FILE *stream, char *fmt, ...)
#define HAVE_MDC_LOOKUP
#elif defined(USE_MDC_LOOKUP)
#include <config.h>
-#include <liblustre.h>
-#include <linux/lustre_lib.h>
+#include <lustre_ioctl.h>
int llapi_file_lookup(int dirfd, const char *name)
{
static void
process_args(int argc, char *argv[])
{
- char c, *cp, *endptr;
+ char *cp, *endptr;
int i, index, offset, tmpend, rc;
char tmp[16];
FILE * seed_file;
*++cp = ':';
}
- while ((c = getopt_long(argc,argv, shortOpts, longOpts,&index)) != -1) {
- switch (c) {
+ while ((rc = getopt_long(argc,argv, shortOpts, longOpts,&index)) != -1) {
+ switch (rc) {
case OPEN:
openflags &= ~(O_CREAT|O_EXCL);
case CREATE:
"specified: --%s\n",
longOpts[index].name);
}
- mode = c;
+ mode = rc;
cmd = (char *)longOpts[index].name;
break;
case NOEXCL:
}
recreate++;
break;
+ case SETXATTR:
+ if (cmd == NULL) {
+ mode = SETXATTR;
+ cmd = (char *)longOpts[index].name;
+ } else if (mode == CREATE || mode == MKNOD) {
+ with_xattr = true;
+ } else {
+ usage(stderr, "--setxattr only makes sense "
+ "with --create, --mknod or alone.\n");
+ }
+ break;
+ case SMALLWRITE:
+ if (mode != CREATE)
+ usage(stderr, "--smallwrite only applies to "
+ "--create.\n");
+ smallwrite = true;
+ break;
case BEGIN:
begin = strtol(optarg, &endptr, 0);
if ((*endptr != 0) || (begin < 0)) {
if ((*endptr != 0) || (iters <= 0)) {
fatal(0, "Invalid --iters value.\n");
}
- if (mode != LOOKUP && mode != OPEN && mode != STAT) {
+ if (mode != LOOKUP && mode != OPEN) {
usage(stderr, "--iters only makes sense with "
- "--lookup, --open, or --stat.\n");
+ "--lookup or --open.\n");
}
break;
case TIME:
break;
case RANDOM:
case READDIR:
- if (mode != LOOKUP && mode != OPEN && mode != STAT) {
+ if (mode != LOOKUP && mode != OPEN) {
fatal(0, "--%s can only be specified with "
- "--lookup, --open, or --stat.\n",
+ "--lookup, or --open.\n",
(char *)longOpts[index].name);
}
- order = c;
+ order = rc;
break;
case IGNORE:
++ignore;
break;
case HELP:
usage(stdout, NULL);
+ break;
+ case MNT:
+ if (strlen(optarg) > (PATH_MAX - 16))
+ fatal(0, "--mnt too long\n");
+ mntfmt = optarg;
+ break;
+ case MNTCOUNT:
+ mnt_count = strtol(optarg, &endptr, 0);
+ if ((*endptr != 0) || (mnt_count <= 0)) {
+ fatal(0, "Invalid --mnt_count value %s.\n",
+ optarg);
+ }
+ break;
+ case MDTCOUNT:
+ mdt_count = strtol(optarg, &endptr, 0);
+ if ((*endptr != 0) || (mdt_count <= 0)) {
+ fatal(0, "Invalid --mdt_count value %s.\n",
+ optarg);
+ }
+ break;
default:
usage(stderr, "unrecognized option: '%c'.\n", optopt);
}
usage(stderr, "too many arguments %d >= %d.\n", optind, argc);
}
- if (mode == CREATE || mode == MKNOD || mode == UNLINK) {
- if (seconds != 0) {
- if (nfiles == 0)
- nfiles = INT_MAX;
- } else if (nfiles == 0) {
- usage(stderr, "--nfiles or --time must be specified "
- "with %s.\n", cmd);
- }
- } else if (mode == LOOKUP || mode == OPEN || mode == STAT) {
+ if ((mnt_count != -1 && mntfmt == NULL) ||
+ (mnt_count == -1 && mntfmt != NULL)) {
+ usage(stderr, "mnt_count and mntfmt must be specified at the "
+ "same time\n");
+ }
+
+ if (mode == CREATE || mode == MKNOD || mode == UNLINK ||
+ mode == STAT || mode == SETXATTR) {
+ if (seconds != 0) {
+ if (nfiles == 0)
+ nfiles = INT_MAX;
+ } else if (nfiles == 0) {
+ usage(stderr, "--nfiles or --time must be specified "
+ "with %s.\n", cmd);
+ }
+ } else if (mode == LOOKUP || mode == OPEN) {
if (seconds != 0) {
if (iters == 0)
iters = INT_MAX;
dmesg("%s: rank %d seed %d (%s).\n", prog, myrank, seed,
(order == RANDOM) ? "random_order" : "readdir_order");
} else {
- usage(stderr, "one --create, --mknod, --open, --stat,"
+ usage(stderr, "one --create, --mknod, --open, --stat,"
#ifdef HAVE_MDC_LOOKUP
- " --lookup,"
+ " --lookup,"
#endif
- " or --unlink must be specifed.");
+ " --unlink or --setxattr must be specifed.");
}
/* support for multiple threads in a dir, set begin/end appropriately.*/
if ((end > tmpend) || (end <= 0))
end -= dirthreads;
+ /* make sure mnt_count <= nthreads, otherwise it might div 0 in
+ * the following test */
+ if (mnt_count > nthreads)
+ mnt_count = nthreads;
+
begin += offset;
if (begin < 0)
begin = INT_MAX;
if (dirfmt == NULL) {
strcpy(dir, ".");
} else {
- sprintf(dir, dirfmt, dirnum);
-
- sprintf(mkdir_cmd, "/bin/mkdir -p %s", dir);
- #ifdef _LIGHTWEIGHT_KERNEL
- printf("NOTICE: not running system(%s)\n", mkdir_cmd);
- #else
- rc = system(mkdir_cmd);
- if (rc) {
- fatal(myrank, "'%s' failed.\n", mkdir_cmd);
- }
- #endif
+ int dir_len = 0;
+
+ if (mntfmt != NULL) {
+ sprintf(dir, mntfmt, (myrank / (nthreads/mnt_count)));
+ strcat(dir, "/");
+ dir_len = strlen(dir);
+ }
+ sprintf(dir + dir_len, dirfmt, dirnum);
+
+ if (mdt_count > 1) {
+ struct stat sb;
+ if (stat(dir, &sb) == 0) {
+ if (!S_ISDIR(sb.st_mode))
+ fatal(myrank, "'%s' is not dir\n", dir);
+ } else if (errno == ENOENT) {
+ sprintf(mkdir_cmd, "lfs mkdir -i %d %s",
+ myrank % mdt_count, dir);
+ } else {
+ fatal(myrank, "'%s' stat failed\n", dir);
+ }
+ } else {
+ sprintf(mkdir_cmd, "mkdir -p %s", dir);
+ }
+
+ dmesg("%d: %s\n", myrank, mkdir_cmd);
+#ifdef _LIGHTWEIGHT_KERNEL
+ printf("NOTICE: not running system(%s)\n", mkdir_cmd);
+#else
+ rc = system(mkdir_cmd);
+ if (rc)
+ fatal(myrank, "'%s' failed.\n", mkdir_cmd);
+#endif
rc = chdir(dir);
if (rc) {
int
main(int argc, char *argv[])
{
- int i, j, fd, rc, nops, lastOps, ag_ops;
- float rate, ag_rate;
- time_t startTime, lastTime, curTime, interval;
+ int i, j, fd, rc, nops, lastOps;
+ int ag_ops = 0;
+ double ag_interval = 0;
+ double ag_rate = 0;
+ double rate, avg_rate, effective_rate;
+ double startTime, curTime, lastTime, interval;
+ time_t timestamp;
char * file;
rc = MPI_Init(&argc, &argv);
process_args(argc, argv);
- startTime = time(0);
+ timestamp = time(0);
if ((myrank == 0) || debug) {
printf("%d: %s starting at %s",
- myrank, hostname, ctime(&startTime));
+ myrank, hostname, ctime(×tamp));
}
/* if we're not measuring creation rates then precreate
* the files we're operating on. */
- if ((mode != CREATE) && (mode != MKNOD) && !ignore) {
+ if ((mode != CREATE) && (mode != MKNOD) && !ignore &&
+ (mode != UNLINK || recreate)) {
/* create the files in reverse order. When we encounter
* a file that already exists, assume the remainder of
* the files exist to save time. The timed performance
dir, strerror(rc));
}
- startTime = time(0);
+ timestamp = time(0);
j = random() % nfiles;
dmesg("%d: %s initializing dir offset %u: %s",
- myrank, hostname, j, ctime(&startTime));
+ myrank, hostname, j, ctime(×tamp));
for (i = 0; i <= j; i++) {
if ((dir_entry = readdir(directory)) == NULL) {
}
}
- lastTime = time(0);
+ timestamp = time(0);
dmesg("%d: index %d, filename %s, offset %ld: "
"%s initialization complete: %s",
myrank, i, dir_entry->d_name, telldir(directory),
- hostname, ctime(&lastTime));
+ hostname, ctime(×tamp));
}
- rc = MPI_Barrier(MPI_COMM_WORLD);
- if (rc != MPI_SUCCESS)
- fatal(myrank, "prep MPI_Barrier failed: %d\n", rc);
-
if (seconds) {
act.sa_handler = sigalrm_handler;
(void)sigemptyset(&act.sa_mask);
alarm(seconds);
}
- startTime = lastTime = time(0);
+ rc = MPI_Barrier(MPI_COMM_WORLD);
+ if (rc != MPI_SUCCESS)
+ fatal(myrank, "prep MPI_Barrier failed: %d\n", rc);
+
+ startTime = lastTime = MPI_Wtime();
nops = lastOps = 0;
switch (mode) {
- case CREATE:
- for (; begin <= end && !alarm_caught; begin += dirthreads) {
- sprintf(filename, filefmt, begin);
- if ((fd = open(filename, openflags, 0644)) < 0) {
- if (((rc = errno) == EINTR) && alarm_caught)
- break;
- fatal(myrank, "open(%s) error: %s\n",
- filename, strerror(rc));
- }
-
- close(fd);
- DISPLAY_PROGRESS();
- }
-
- dmesg("%d: created %d files, last file '%s'.\n",
- myrank, nops, filename);
- break;
+ case CREATE:
+ for (; begin <= end && !alarm_caught; begin += dirthreads) {
+ snprintf(filename, sizeof(filename), filefmt, begin);
+ fd = open(filename, openflags, 0644);
+ if (fd < 0) {
+ rc = errno;
+ if (rc == EINTR && alarm_caught)
+ break;
+ fatal(myrank, "open(%s) error: %s\n",
+ filename, strerror(rc));
+ }
+
+ if (with_xattr) {
+ rc = fsetxattr(fd, xattrname, xattrbuf,
+ xattrlen, XATTR_CREATE);
+ if (rc) {
+ rc = errno;
+ if (rc == EINTR && alarm_caught)
+ break;
+ fatal(myrank,
+ "setxattr(%s) error: %s\n",
+ filename, strerror(rc));
+ }
+ }
+ if (smallwrite) {
+ rc = write(fd, xattrbuf, xattrlen);
+ if (rc < 0) {
+ rc = errno;
+ if (rc == EINTR && alarm_caught)
+ break;
+ fatal(myrank,
+ "write(%s) error: %s\n",
+ filename, strerror(rc));
+ }
+ }
+
+ close(fd);
+ nops++;
+ DISPLAY_PROGRESS();
+ }
+
+ dmesg("%d: created %d files, last file '%s'.\n",
+ myrank, nops, filename);
+ break;
#ifdef HAVE_MDC_LOOKUP
case LOOKUP:
fd = open(dir, O_RDONLY);
"error: %s\n", filename, strerror(rc));
}
+ nops++;
DISPLAY_PROGRESS();
}
break;
#endif
- case MKNOD:
- for (; begin <= end && !alarm_caught; begin += dirthreads) {
- sprintf(filename, filefmt, begin);
- rc = mknod(filename, S_IFREG| 0644, 0);
- if (rc) {
- if (((rc = errno) == EINTR) && alarm_caught)
- break;
- fatal(myrank, "mknod(%s) error: %s\n",
- filename, strerror(rc));
- }
-
- DISPLAY_PROGRESS();
- }
- break;
+ case MKNOD:
+ for (; begin <= end && !alarm_caught; begin += dirthreads) {
+ snprintf(filename, sizeof(filename), filefmt, begin);
+ rc = mknod(filename, S_IFREG | 0644, 0);
+ if (rc) {
+ rc = errno;
+ if (rc == EINTR && alarm_caught)
+ break;
+ fatal(myrank, "mknod(%s) error: %s\n",
+ filename, strerror(rc));
+ }
+
+ if (with_xattr) {
+ rc = setxattr(filename, xattrname, xattrbuf,
+ xattrlen, XATTR_CREATE);
+ if (rc) {
+ rc = errno;
+ if (rc == EINTR && alarm_caught)
+ break;
+ fatal(myrank,
+ "setxattr(%s) error: %s\n",
+ filename, strerror(rc));
+ }
+ }
+
+ nops++;
+ DISPLAY_PROGRESS();
+ }
+ break;
case OPEN:
for (; nops < iters && !alarm_caught;) {
file = next_file();
close(fd);
+ nops++;
DISPLAY_PROGRESS();
}
break;
case STAT:
- for (; nops < iters && !alarm_caught;) {
- rc = stat(file = next_file(), &statbuf);
+ for (; begin <= end && !alarm_caught; begin += dirthreads) {
+ sprintf(filename, filefmt, begin);
+ rc = stat(filename, &statbuf);
if (rc) {
if (((rc = errno) == EINTR) && alarm_caught)
break;
+ if (((rc = errno) == ENOENT) && ignore)
+ continue;
fatal(myrank, "stat(%s) error: %s\n",
- file, strerror(rc));
+ filename, strerror(rc));
}
+ nops++;
DISPLAY_PROGRESS();
}
break;
if (rc) {
if (((rc = errno) == EINTR) && alarm_caught)
break;
- if (((rc = errno) == ENOENT) && ignore)
- continue;
+ if ((rc = errno) == ENOENT) {
+ if (ignore)
+ continue;
+ /* no more files to unlink */
+ break;
+ }
fatal(myrank, "unlink(%s) error: %s\n",
filename, strerror(rc));
}
+ nops++;
DISPLAY_PROGRESS();
}
break;
+ case SETXATTR:
+ for (; begin <= end && !alarm_caught; begin += dirthreads) {
+ snprintf(filename, sizeof(filename), filefmt, begin);
+ rc = setxattr(filename, xattrname, xattrbuf, xattrlen,
+ XATTR_CREATE);
+ if (rc) {
+ rc = errno;
+ if (rc == EINTR && alarm_caught)
+ break;
+ if (rc == ENOENT && ignore)
+ continue;
+ fatal(myrank, "setxattr(%s) error: %s\n",
+ filename, strerror(rc));
+ }
+
+ nops++;
+ DISPLAY_PROGRESS();
+ }
+ break;
}
- curTime = time(0);
+ rc = MPI_Barrier(MPI_COMM_WORLD);
+ if (rc != MPI_SUCCESS)
+ fatal(myrank, "prep MPI_Barrier failed: %d\n", rc);
+ curTime = MPI_Wtime();
interval = curTime - startTime;
- rate = (float)(nops);
- if (interval != 0)
- rate /= (float)interval;
+ rate = (double) (nops) / interval;
rc = MPI_Reduce(&nops, &ag_ops, 1, MPI_INT, MPI_SUM, 0,
MPI_COMM_WORLD);
fatal(myrank, "Failure in MPI_Reduce of total ops.\n");
}
- rc = MPI_Reduce(&rate, &ag_rate, 1, MPI_FLOAT, MPI_SUM, 0,
+ rc = MPI_Reduce(&interval, &ag_interval, 1, MPI_DOUBLE, MPI_SUM, 0,
+ MPI_COMM_WORLD);
+ if (rc != MPI_SUCCESS) {
+ fatal(myrank, "Failure in MPI_Reduce of total interval.\n");
+ }
+
+ rc = MPI_Reduce(&rate, &ag_rate, 1, MPI_DOUBLE, MPI_SUM, 0,
MPI_COMM_WORLD);
if (rc != MPI_SUCCESS) {
fatal(myrank, "Failure in MPI_Reduce of aggregated rate.\n");
}
if (myrank == 0) {
- printf("Rate: %.2f %ss/sec (total: %d threads %d %ss %lu secs)"
- "\n", ag_rate, cmd, nthreads, ag_ops, cmd, interval);
+ curTime = MPI_Wtime();
+ interval = curTime - startTime;
+ effective_rate = (double) ag_ops / interval;
+ avg_rate = (double) ag_ops / ag_interval;
+
+ printf("Rate: %.2f eff %.2f aggr %.2f avg client %ss/sec "
+ "(total: %d threads %d %ss %d dirs %d threads/dir %.2f secs)\n",
+ effective_rate, ag_rate, avg_rate, cmd, nthreads, ag_ops,
+ cmd, ndirs, dirthreads, interval);
+ if (mode == UNLINK && !recreate && !ignore && ag_ops != nfiles)
+ printf("Warning: only unlinked %d files instead of %d"
+ "\n", ag_ops, nfiles);
}
if (recreate) {
}
}
- curTime = time(0);
+ timestamp = time(0);
if ((myrank == 0) || debug) {
printf("%d: %s finished at %s",
- myrank, hostname, ctime(&curTime));
+ myrank, hostname, ctime(×tamp));
}
MPI_Finalize();