summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2012-03-05 21:38:12 +0100
committerJens Axboe <axboe@kernel.dk>2012-03-05 21:38:12 +0100
commite5bd13470beaeed9c4a6835b7b92265fb94173a9 (patch)
tree7aa697a5c3a7507744d132c25b110acef5ec052a
parentc551f65a0a2a972c19f9c274f3cf24f4b6d98680 (diff)
downloadfio-e5bd13470beaeed9c4a6835b7b92265fb94173a9.tar.gz
gfio: add latency bucket display
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--gfio.c91
-rw-r--r--stat.c4
-rw-r--r--stat.h2
3 files changed, 95 insertions, 2 deletions
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)