From: Jens Axboe Date: Mon, 5 Mar 2012 20:38:12 +0000 (+0100) Subject: gfio: add latency bucket display X-Git-Tag: gfio-0.1~262 X-Git-Url: https://git.kernel.dk/?a=commitdiff_plain;h=e5bd13470beaeed9c4a6835b7b92265fb94173a9;p=fio.git gfio: add latency bucket display Signed-off-by: Jens Axboe --- diff --git a/gfio.c b/gfio.c index 3602aa33..2c0c2cc5 100644 --- a/gfio.c +++ b/gfio.c @@ -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(); diff --git a/stat.c b/stat.c index e4ddfa8c..0fd8b725 100644 --- a/stat.c +++ b/stat.c @@ -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); } diff --git a/stat.h b/stat.h index 78e46711..fb1bafde 100644 --- a/stat.h +++ b/stat.h @@ -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)