[PATCH] fio: remove write_stat stuff and calc latency average and deviation
authorJens Axboe <axboe@suse.de>
Fri, 21 Oct 2005 16:41:03 +0000 (18:41 +0200)
committerJens Axboe <axboe@suse.de>
Fri, 21 Oct 2005 16:41:03 +0000 (18:41 +0200)
Makefile
README.fio
fio.c

index 778ce00dd1676f686b245baddeb0467007606e21..72d7cb0bb061c43ae6e87dd22e7c4002f697f0e3 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@ dops: dops.o
        $(CC) $(CFLAGS) -o $@ $(filter %.o,$^) -laio
 
 fio: fio.o
-       $(CC) $(CFLAGS) -o $@ $(filter %.o,$^) -lpthread -laio
+       $(CC) $(CFLAGS) -o $@ $(filter %.o,$^) -lpthread -laio -lm
 
 sgioread: sgioread.o
        $(CC) $(CFLAGS) -o $@ $(filter %.o,$^)
index e542600fbdb684f43a7abcb866f00048a0d7899d..2d13814600a40dc25dd6bc56357464da98efd6af 100644 (file)
@@ -13,7 +13,6 @@ $ fio
        -s IO is sequential
        -b block size in KiB for each io
        -t <sec> Runtime in seconds
-       -w Write statistics
        -r For random io, sequence must be repeatable
        -R <on> If one thread fails to meet rate, quit all
        -o <on> Use direct IO is 1, buffered if 0
diff --git a/fio.c b/fio.c
index 3a21fabe6f919d0201dfb713a19c81dc36ea3daa..6245209a8189168f0cd995bf7e2afc2f2a1b8dd1 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -29,6 +29,7 @@
 #include <ctype.h>
 #include <sched.h>
 #include <libaio.h>
+#include <math.h>
 #include <sys/time.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -94,7 +95,6 @@ enum {
 
 #define ALIGN(buf)     (char *) (((unsigned long) (buf) + MASK) & ~(MASK))
 
-static int write_stat = DEF_WRITESTAT;
 static int repeatable = DEF_RAND_REPEAT;
 static int rate_quit = 1;
 
@@ -124,7 +124,6 @@ struct thread_data {
        int thread_number;
        int error;
        int fd;
-       int stat_fd;
        pid_t pid;
        char *buf;
        volatile int terminate;
@@ -166,11 +165,11 @@ struct thread_data {
        struct drand48_data random_state;
 
        /*
-        * bandwidth stat
+        * bandwidth and latency stats
         */
        unsigned long stat_time;
-       unsigned long stat_time_last;
-       unsigned long stat_blocks_last;
+       unsigned long stat_time_sq;
+       unsigned long stat_samples;
 
        struct timeval start;
 };
@@ -220,32 +219,6 @@ static int init_random_state(struct thread_data *td)
        return 0;
 }
 
-static void shutdown_stat_file(struct thread_data *td)
-{
-       if (td->stat_fd != -1) {
-               fsync(td->stat_fd);
-               close(td->stat_fd);
-       }
-}
-
-static int init_stat_file(struct thread_data *td)
-{
-       char n[256];
-
-       if (!write_stat)
-               return 0;
-
-       sprintf(n, "fio_thread%d.stat", td->thread_number);
-       td->stat_fd = open(n, O_WRONLY | O_CREAT | O_TRUNC, 0644);
-       if (td->stat_fd == -1) {
-               perror("open stat file");
-               td->error = errno;
-               return 1;
-       }
-
-       return 0;
-}
-
 static unsigned long utime_since(struct timeval *s, struct timeval *e)
 {
        double sec, usec;
@@ -310,23 +283,9 @@ static unsigned long get_next_offset(struct thread_data *td)
 
 static void add_stat_sample(struct thread_data *td, unsigned long msec)
 {
-       char sample[256];
-
-       if (!td->stat_fd)
-               return;
-
        td->stat_time += msec;
-       td->stat_time_last += msec;
-       td->stat_blocks_last++;
-
-       if (td->stat_time_last >= 500) {
-               unsigned long rate = td->stat_blocks_last * td->bs / (td->stat_time_last);
-
-               td->stat_time_last = 0;
-               td->stat_blocks_last = 0;
-               sprintf(sample, "%lu, %lu\n", td->stat_time, rate);
-               write(td->stat_fd, sample, strlen(sample));
-       }
+       td->stat_time_sq += msec * msec;
+       td->stat_samples++;
 }
 
 static void usec_sleep(int usec)
@@ -721,8 +680,6 @@ static void *thread_main(int shm_id, int offset, char *argv[])
 
        if (init_random_state(td))
                goto err;
-       if (init_stat_file(td))
-               goto err;
 
        if (td->ddir == DDIR_READ) {
                if (fstat(td->fd, &st) == -1) {
@@ -766,7 +723,6 @@ static void *thread_main(int shm_id, int offset, char *argv[])
        td->runtime = mtime_since_now(&td->start);
        ret = 0;
 err:
-       shutdown_stat_file(td);
        if (td->use_aio)
                cleanup_aio(td);
        if (td->fd != -1) {
@@ -793,6 +749,7 @@ static void show_thread_status(struct thread_data *td)
 {
        int prio, prio_class;
        unsigned long bw = 0;
+       double nr, mean, dev;
 
        if (!td->io_blocks && !td->error)
                return;
@@ -803,7 +760,11 @@ static void show_thread_status(struct thread_data *td)
        prio = td->ioprio & 0xff;
        prio_class = td->ioprio >> IOPRIO_CLASS_SHIFT;
 
-       printf("thread%d (%s): err=%2d, prio=%1d/%1d maxl=%5lumsec, io=%6luMiB, bw=%6luKiB/sec\n", td->thread_number, td->ddir == DDIR_READ ? " read": "write", td->error, prio_class, prio, td->max_latency, td->io_blocks * td->bs >> 20, bw);
+       nr = (double) td->stat_samples;
+       mean = (double) td->stat_time / nr;
+       dev = sqrt(((double) td->stat_time_sq - (mean * mean) / nr) / (nr - 1));
+
+       printf("Client%d: err=%2d, io=%6luMiB, bw=%6luKiB/sec, latmax=%5lu, latavg=%5.02f, latdev=%5.02f\n", td->thread_number, td->error, td->io_blocks * td->bs >> 20, bw, td->max_latency, mean, dev);
 }
 
 static int setup_rate(struct thread_data *td)
@@ -861,7 +822,6 @@ static int add_job(struct thread_data *td, const char *filename, int prioclass,
                return 0;
 
        strcpy(td->file_name, filename);
-       td->stat_fd = -1;
        sem_init(&td->mutex, 1, 0);
        td->min_latency = 10000000;
        td->ioprio = (prioclass << IOPRIO_CLASS_SHIFT) | prio;
@@ -872,7 +832,7 @@ static int add_job(struct thread_data *td, const char *filename, int prioclass,
        if (setup_rate(td))
                return -1;
 
-       printf("Client%d: file=%s, rw=%d, prio=%d, seq=%d, odir=%d, bs=%d, rate=%d, aio=%d, aio_depth=%d\n", td->thread_number, filename, td->ddir, td->ioprio, td->sequential, td->odirect, td->bs, td->rate, td->use_aio, td->aio_depth);
+       printf("Client%d: file=%s, rw=%d, prio=%d/%d, seq=%d, odir=%d, bs=%d, rate=%d, aio=%d, aio_depth=%d\n", td->thread_number, filename, td->ddir, prioclass, prio, td->sequential, td->odirect, td->bs, td->rate, td->use_aio, td->aio_depth);
        return 0;
 }
 
@@ -1249,10 +1209,6 @@ static int parse_options(int argc, char *argv[])
                                parm++;
                                def_thread.timeout = atoi(parm);
                                break;
-                       case 'w':
-                               parm++;
-                               write_stat = !!atoi(parm);
-                               break;
                        case 'r':
                                parm++;
                                repeatable = !!atoi(parm);
@@ -1438,7 +1394,7 @@ int main(int argc, char *argv[])
                return 1;
        }
 
-       printf("%s: %s, bs=%uKiB, timeo=%u, write_stat=%u, odirect=%d\n", argv[0], def_thread.sequential ? "sequential" : "random", def_thread.bs >> 10, def_thread.timeout, write_stat, def_thread.odirect);
+       printf("%s: %s, bs=%uKiB, timeo=%u, odirect=%d\n", argv[0], def_thread.sequential ? "sequential" : "random", def_thread.bs >> 10, def_thread.timeout, def_thread.odirect);
 
        run_threads(argv);