diff options
author | Jens Axboe <axboe@kernel.dk> | 2012-03-05 21:38:12 +0100 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2012-03-05 21:38:12 +0100 |
commit | e5bd13470beaeed9c4a6835b7b92265fb94173a9 (patch) | |
tree | 7aa697a5c3a7507744d132c25b110acef5ec052a | |
parent | c551f65a0a2a972c19f9c274f3cf24f4b6d98680 (diff) | |
download | fio-e5bd13470beaeed9c4a6835b7b92265fb94173a9.tar.gz |
gfio: add latency bucket display
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | gfio.c | 91 | ||||
-rw-r--r-- | stat.c | 4 | ||||
-rw-r--r-- | stat.h | 2 |
3 files changed, 95 insertions, 2 deletions
@@ -472,6 +472,95 @@ static void gfio_show_ddir_status(GtkWidget *mbox, struct group_run_stats *rs, free(iops_p); } +static GtkWidget *gfio_output_lat_buckets(double *lat, unsigned int num, + const char **labels) +{ + GtkWidget *tree_view; + GtkTreeSelection *selection; + GtkListStore *model; + GtkTreeIter iter; + GType *types; + int i, skipped; + + /* + * Check if all are empty, in which case don't bother + */ + for (i = 0, skipped = 0; i < num; i++) + if (lat[i] <= 0.0) + skipped++; + + if (skipped == num) + return NULL; + + types = malloc(num * sizeof(GType)); + + for (i = 0; i < num; i++) + types[i] = G_TYPE_STRING; + + model = gtk_list_store_newv(num, types); + free(types); + types = NULL; + + tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)); + gtk_widget_set_can_focus(tree_view, FALSE); + + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)); + gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_BROWSE); + + for (i = 0; i < num; i++) + tree_view_column(tree_view, i, labels[i], ALIGN_RIGHT | UNSORTABLE); + + gtk_list_store_append(model, &iter); + + for (i = 0; i < num; i++) { + char fbuf[32]; + + if (lat[i] <= 0.0) + sprintf(fbuf, "0.00"); + else + sprintf(fbuf, "%3.2f%%", lat[i]); + + gtk_list_store_set(model, &iter, i, fbuf, -1); + } + + return tree_view; +} + +static void gfio_show_latency_buckets(GtkWidget *vbox, struct thread_stat *ts) +{ + GtkWidget *box, *frame, *tree_view; + double io_u_lat_u[FIO_IO_U_LAT_U_NR]; + double io_u_lat_m[FIO_IO_U_LAT_M_NR]; + const char *uranges[] = { "2", "4", "10", "20", "50", "100", + "250", "500", "750", "1000", }; + const char *mranges[] = { "2", "4", "10", "20", "50", "100", + "250", "500", "750", "1000", "2000", + ">= 2000", }; + + stat_calc_lat_u(ts, io_u_lat_u); + stat_calc_lat_m(ts, io_u_lat_m); + + tree_view = gfio_output_lat_buckets(io_u_lat_u, FIO_IO_U_LAT_U_NR, uranges); + if (tree_view) { + frame = gtk_frame_new("Latency buckets (usec)"); + gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5); + + box = gtk_hbox_new(FALSE, 3); + gtk_container_add(GTK_CONTAINER(frame), box); + gtk_box_pack_start(GTK_BOX(box), tree_view, TRUE, FALSE, 3); + } + + tree_view = gfio_output_lat_buckets(io_u_lat_m, FIO_IO_U_LAT_M_NR, mranges); + if (tree_view) { + frame = gtk_frame_new("Latency buckets (msec)"); + gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5); + + box = gtk_hbox_new(FALSE, 3); + gtk_container_add(GTK_CONTAINER(frame), box); + gtk_box_pack_start(GTK_BOX(box), tree_view, TRUE, FALSE, 3); + } +} + static void gfio_display_ts(struct fio_client *client, struct thread_stat *ts, struct group_run_stats *rs) { @@ -516,6 +605,8 @@ static void gfio_display_ts(struct fio_client *client, struct thread_stat *ts, if (ts->io_bytes[DDIR_WRITE]) gfio_show_ddir_status(vbox, rs, ts, DDIR_WRITE); + gfio_show_latency_buckets(vbox, ts); + gtk_widget_show_all(dialog); gdk_threads_leave(); @@ -327,12 +327,12 @@ static void stat_calc_lat(struct thread_stat *ts, double *dst, } } -static void stat_calc_lat_u(struct thread_stat *ts, double *io_u_lat) +void stat_calc_lat_u(struct thread_stat *ts, double *io_u_lat) { stat_calc_lat(ts, io_u_lat, ts->io_u_lat_u, FIO_IO_U_LAT_U_NR); } -static void stat_calc_lat_m(struct thread_stat *ts, double *io_u_lat) +void stat_calc_lat_m(struct thread_stat *ts, double *io_u_lat) { stat_calc_lat(ts, io_u_lat, ts->io_u_lat_m, FIO_IO_U_LAT_M_NR); } @@ -200,6 +200,8 @@ extern void init_group_run_stat(struct group_run_stats *gs); extern void eta_to_str(char *str, unsigned long eta_sec); extern int calc_lat(struct io_stat *is, unsigned long *min, unsigned long *max, double *mean, double *dev); extern unsigned int calc_clat_percentiles(unsigned int *io_u_plat, unsigned long nr, fio_fp64_t *plist, unsigned int **output, unsigned int *maxv, unsigned int *minv); +extern void stat_calc_lat_m(struct thread_stat *ts, double *io_u_lat); +extern void stat_calc_lat_u(struct thread_stat *ts, double *io_u_lat); static inline int usec_to_msec(unsigned long *min, unsigned long *max, double *mean, double *dev) |