diff options
author | Andrew Tridgell <tridge@samba.org> | 2004-11-25 23:05:43 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:06:10 -0500 |
commit | b6b01064279c0cf5bae8b2324c760f1f7f6be457 (patch) | |
tree | cbd19dcceca038b6192dca44c46189d94da234e8 /source4 | |
parent | d019557a53b7e624724cd23cce025731c9808f50 (diff) | |
download | samba-b6b01064279c0cf5bae8b2324c760f1f7f6be457.tar.gz samba-b6b01064279c0cf5bae8b2324c760f1f7f6be457.tar.bz2 samba-b6b01064279c0cf5bae8b2324c760f1f7f6be457.zip |
r3976: changed NBENCH to use the same recording method as the latest dbench,
where the warmup phase continues until all clients have done some file
IO. This gives more repeatable results when under high load
(This used to be commit aca0658f6dfe8b7c90afcac87e8cc68965a4288d)
Diffstat (limited to 'source4')
-rw-r--r-- | source4/lib/time.c | 23 | ||||
-rw-r--r-- | source4/torture/nbench/nbench.c | 31 | ||||
-rw-r--r-- | source4/torture/nbench/nbio.c | 105 |
3 files changed, 91 insertions, 68 deletions
diff --git a/source4/lib/time.c b/source4/lib/time.c index b13ad24b34..8d477fac02 100644 --- a/source4/lib/time.c +++ b/source4/lib/time.c @@ -477,13 +477,21 @@ BOOL timeval_expired(struct timeval *tv) } /* + return the number of seconds elapsed between two times +*/ +double timeval_elapsed2(struct timeval *tv1, struct timeval *tv2) +{ + return (tv2->tv_sec - tv1->tv_sec) + + (tv2->tv_usec - tv1->tv_usec)*1.0e-6; +} + +/* return the number of seconds elapsed since a given time */ double timeval_elapsed(struct timeval *tv) { struct timeval tv2 = timeval_current(); - return (tv2.tv_sec - tv->tv_sec) + - (tv2.tv_usec - tv->tv_usec)*1.0e-6; + return timeval_elapsed2(tv, &tv2); } /* @@ -498,6 +506,17 @@ struct timeval timeval_min(struct timeval *tv1, struct timeval *tv2) } /* + return the greater of two timevals +*/ +struct timeval timeval_max(struct timeval *tv1, struct timeval *tv2) +{ + if (tv1->tv_sec > tv2->tv_sec) return *tv1; + if (tv1->tv_sec < tv2->tv_sec) return *tv2; + if (tv1->tv_usec > tv2->tv_usec) return *tv1; + return *tv2; +} + +/* return the difference between two timevals as a timeval if tv2 comes after tv1, then return a zero timeval (this is *tv1 - *tv2) diff --git a/source4/torture/nbench/nbench.c b/source4/torture/nbench/nbench.c index 1c90658f49..afd71537a9 100644 --- a/source4/torture/nbench/nbench.c +++ b/source4/torture/nbench/nbench.c @@ -37,11 +37,8 @@ static BOOL run_netbench(struct smbcli_state *cli, int client) fstring params[20]; const char *p; BOOL correct = True; - struct timeval tv; - tv = timeval_current(); - - nb_setup(cli, client, warmup); + nb_setup(cli, client); asprintf(&cname, "client%d", client+1); @@ -56,17 +53,6 @@ again: while (fgets(line, sizeof(line)-1, f)) { NTSTATUS status; - if (warmup && - timeval_elapsed(&tv) >= warmup) { - warmup = 0; - nb_warmup_done(); - tv = timeval_current(); - } - - if (timeval_elapsed(&tv) >= timelimit) { - goto done; - } - nbench_line_count++; line[strlen(line)-1] = 0; @@ -147,6 +133,8 @@ again: } else { printf("[%d] Unknown operation %s\n", nbench_line_count, params[0]); } + + if (nb_tick()) goto done; } rewind(f); @@ -154,7 +142,6 @@ again: done: fclose(f); - nb_cleanup(cname); if (!torture_close_connection(cli)) { correct = False; @@ -188,10 +175,11 @@ BOOL torture_nbench(void) return False; } - nb_setup(cli, -1, warmup); - nb_deltree("\\clients"); + if (!torture_setup_dir(cli, "\\clients")) { + return False; + } - nbio_shmem(torture_nprocs); + nbio_shmem(torture_nprocs, timelimit, warmup); printf("Running for %d seconds with load '%s' and warmup %d secs\n", timelimit, loadfile, warmup); @@ -201,7 +189,8 @@ BOOL torture_nbench(void) torture_create_procs(run_netbench, &correct); alarm(0); - printf("\nThroughput %g MB/sec\n", - 1.0e-6 * nbio_total() / timelimit); + smbcli_deltree(cli->tree, "\\clients"); + + printf("\nThroughput %g MB/sec\n", nbio_result()); return correct; } diff --git a/source4/torture/nbench/nbio.c b/source4/torture/nbench/nbio.c index 98967f2523..e3c40f9ba1 100644 --- a/source4/torture/nbench/nbio.c +++ b/source4/torture/nbench/nbio.c @@ -27,11 +27,12 @@ #define MAX_FILES 100 extern int nbench_line_count; -static int nbio_id; +static int nbio_id = -1; static int nprocs; static BOOL bypass_io; -static int warmup; -static struct timeval tv; +static struct timeval tv_start, tv_end; +static int warmup, timelimit; +static int in_cleanup; struct ftable { struct ftable *next, *prev; @@ -42,67 +43,90 @@ struct ftable { static struct ftable *ftable; static struct { - double bytes_in, bytes_out; + double bytes, warmup_bytes; int line; int done; } *children; -double nbio_total(void) +double nbio_result(void) { int i; double total = 0; for (i=0;i<nprocs;i++) { - total += children[i].bytes_out + children[i].bytes_in; + total += children[i].bytes - children[i].warmup_bytes; } - return total; + return 1.0e-6 * total / timeval_elapsed2(&tv_start, &tv_end); } -void nb_warmup_done(void) +BOOL nb_tick(void) { - children[nbio_id].bytes_out = 0; - children[nbio_id].bytes_in = 0; + return children[nbio_id].done; } void nb_alarm(int sig) { int i; - int lines=0, num_clients=0; + int lines=0; double t; + int in_warmup = 0; if (nbio_id != -1) return; for (i=0;i<nprocs;i++) { + if (children[i].bytes == 0) { + in_warmup = 1; + } lines += children[i].line; - if (!children[i].done) num_clients++; } - t = timeval_elapsed(&tv); + t = timeval_elapsed(&tv_start); - if (warmup) { + if (!in_warmup && warmup>0 && t > warmup) { + tv_start = timeval_current(); + warmup = 0; + for (i=0;i<nprocs;i++) { + children[i].warmup_bytes = children[i].bytes; + } + goto next; + } + if (t < warmup) { + in_warmup = 1; + } else if (!in_warmup && !in_cleanup && t > timelimit) { + for (i=0;i<nprocs;i++) { + children[i].done = 1; + } + tv_end = timeval_current(); + in_cleanup = 1; + } + if (t < 1) { + goto next; + } + if (!in_cleanup) { + tv_end = timeval_current(); + } + + if (in_warmup) { printf("%4d %8d %.2f MB/sec warmup %.0f sec \n", - num_clients, lines/nprocs, - 1.0e-6 * nbio_total() / t, - t); + nprocs, lines/nprocs, + nbio_result(), t); + } else if (in_cleanup) { + printf("%4d %8d %.2f MB/sec cleanup %.0f sec \n", + nprocs, lines/nprocs, + nbio_result(), t); } else { printf("%4d %8d %.2f MB/sec execute %.0f sec \n", - num_clients, lines/nprocs, - 1.0e-6 * nbio_total() / t, - t); - } - - if (warmup && t >= warmup) { - tv = timeval_current(); - warmup = 0; + nprocs, lines/nprocs, + nbio_result(), t); } fflush(stdout); - +next: signal(SIGALRM, nb_alarm); alarm(1); } -void nbio_shmem(int n) +void nbio_shmem(int n, int t_timelimit, int t_warmup) { nprocs = n; children = shm_setup(sizeof(*children) * nprocs); @@ -110,6 +134,11 @@ void nbio_shmem(int n) printf("Failed to setup shared memory!\n"); exit(1); } + memset(children, 0, sizeof(*children) * nprocs); + timelimit = t_timelimit; + warmup = t_warmup; + in_cleanup = 0; + tv_start = timeval_current(); } static struct ftable *find_ftable(int handle) @@ -152,15 +181,10 @@ static BOOL oplock_handler(struct smbcli_transport *transport, uint16_t tid, uin return smbcli_oplock_ack(tree, fnum, level); } -void nb_setup(struct smbcli_state *cli, int id, int warmupt) +void nb_setup(struct smbcli_state *cli, int id) { - warmup = warmupt; nbio_id = id; c = cli; - tv = timeval_current(); - if (children) { - children[nbio_id].done = 0; - } if (bypass_io) printf("skipping I/O\n"); @@ -297,7 +321,7 @@ void nb_writex(int handle, int offset, int size, int ret_size, NTSTATUS status) io.writex.out.nwritten, ret_size); } - children[nbio_id].bytes_out += ret_size; + children[nbio_id].bytes += ret_size; } void nb_write(int handle, int offset, int size, int ret_size, NTSTATUS status) @@ -334,7 +358,7 @@ void nb_write(int handle, int offset, int size, int ret_size, NTSTATUS status) io.write.out.nwritten, ret_size); } - children[nbio_id].bytes_out += ret_size; + children[nbio_id].bytes += ret_size; } @@ -424,7 +448,7 @@ void nb_readx(int handle, int offset, int size, int ret_size, NTSTATUS status) exit(1); } - children[nbio_id].bytes_in += ret_size; + children[nbio_id].bytes += ret_size; } void nb_close(int handle, NTSTATUS status) @@ -649,12 +673,3 @@ void nb_deltree(const char *dname) smbcli_rmdir(c->tree, dname); } -void nb_cleanup(const char *cname) -{ - char *dname = NULL; - asprintf(&dname, "\\clients\\%s", cname); - nb_deltree(dname); - free(dname); - smbcli_rmdir(c->tree, "clients"); - children[nbio_id].done = 1; -} |