From 951ea56c26b7d828c2783f98ca5e2df3e9dad6c8 Mon Sep 17 00:00:00 2001 From: "Alan D. Brunelle" Date: Wed, 5 Dec 2007 18:08:10 -0500 Subject: [PATCH] Added in Q2D histograms (requires -A) As an example, the buckets are in seconds: ==================== Q2D Histogram ==================== DEV | <.005 <.010 <.025 <.050 <.075 <.100 <.250 <.500 < 1.0 >=1.0 --------- | ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ( 66, 80) | 61.2 7.9 12.1 7.9 3.0 1.4 1.5 0.2 0.0 4.6 ( 65,192) | 42.3 5.0 8.7 30.0 8.9 3.0 1.8 0.1 0.0 0.1 ( 65,128) | 34.3 5.3 8.9 32.0 9.7 3.7 5.3 0.6 0.0 0.1 ( 66, 0) | 45.5 9.9 19.0 14.8 4.6 1.2 0.3 0.0 0.0 4.7 ( 65, 48) | 50.2 4.6 7.2 27.6 6.9 2.1 1.1 0.0 0.0 0.1 ( 66, 32) | 66.4 6.7 10.9 7.0 2.5 1.1 0.6 0.1 0.0 4.7 ( 65,224) | 33.9 9.6 20.6 17.8 7.3 3.1 3.3 0.5 0.1 3.8 ( 65,112) | 35.3 5.2 8.7 30.8 9.3 3.9 5.6 0.9 0.1 0.1 ( 65, 80) | 57.9 4.6 6.6 25.2 4.7 0.8 0.2 0.0 0.0 0.1 ( 65,240) | 62.6 8.1 13.1 7.7 2.3 0.6 0.5 0.0 0.0 5.1 ( 66,112) | 59.6 8.0 13.1 8.6 3.3 1.5 1.2 0.1 0.0 4.6 ( 65,144) | 45.8 5.1 7.9 29.3 7.8 2.5 1.4 0.0 0.0 0.1 ( 65,176) | 43.2 5.2 8.9 30.8 8.3 2.5 1.0 0.0 0.0 0.1 ( 66, 16) | 77.0 5.4 7.4 3.3 0.7 0.3 0.7 0.1 0.0 5.0 ( 65, 96) | 54.6 4.9 7.2 26.6 5.3 1.0 0.2 0.0 0.0 0.1 ( 66, 48) | 71.0 6.8 10.5 5.4 0.9 0.1 0.1 0.0 0.0 5.2 ( 65,208) | 43.5 5.6 8.5 31.0 7.2 2.2 1.9 0.0 0.0 0.1 ( 66,128) | 69.5 7.0 10.3 6.2 1.5 0.3 0.1 0.0 0.0 5.0 ( 65, 64) | 59.9 4.2 6.0 24.6 4.2 0.8 0.1 0.0 0.0 0.1 ( 66, 64) | 62.6 8.1 12.7 7.9 2.4 0.6 0.1 0.0 0.0 5.4 ========== | ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== AVG | 52.9 6.2 10.0 20.1 5.3 1.7 1.4 0.2 0.0 2.1 --- btt/Makefile | 2 +- btt/devs.c | 4 ++ btt/doc/btt.tex | 21 ++++++++ btt/globals.h | 11 +++++ btt/output.c | 48 ++++++++++++++++++ btt/q2d.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++ btt/trace_issue.c | 4 ++ 7 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 btt/q2d.c diff --git a/btt/Makefile b/btt/Makefile index 5281a94..094f77f 100644 --- a/btt/Makefile +++ b/btt/Makefile @@ -17,7 +17,7 @@ LIBS = $(PLIBS) $(ELIBS) OBJS = args.o bt_timeline.o devmap.o devs.o dip_rb.o iostat.o latency.o \ misc.o output.o proc.o seek.o trace.o trace_complete.o trace_im.o \ trace_issue.o trace_queue.o trace_remap.o trace_requeue.o \ - ../rbtree.o mmap.o trace_plug.o bno_dump.o unplug_hist.o + ../rbtree.o mmap.o trace_plug.o bno_dump.o unplug_hist.o q2d.o all: depend $(PROGS) diff --git a/btt/devs.c b/btt/devs.c index 449d452..6a0fcfc 100644 --- a/btt/devs.c +++ b/btt/devs.c @@ -131,6 +131,8 @@ void dip_exit(void) seeki_exit(dip->q2q_handle); bno_dump_exit(dip->bno_dump_handle); unplug_hist_exit(dip->unplug_hist_handle); + if (output_all_data) + q2d_release(dip->q2d_priv); free(dip); } } @@ -167,6 +169,8 @@ struct d_info *dip_add(__u32 device, struct io *iop) list_add_tail(&dip->all_head, &all_devs); dip->start_time = BIT_TIME(iop->t.time); dip->pre_culling = 1; + if (output_all_data) + dip->q2d_priv = q2d_init(); n_devs++; } diff --git a/btt/doc/btt.tex b/btt/doc/btt.tex index f35cf1f..3d3abd2 100644 --- a/btt/doc/btt.tex +++ b/btt/doc/btt.tex @@ -336,6 +336,27 @@ pdflush 0.000000790 0.000006752 0.247231307 179791 \item[Per Device Averages] The average columns from the above charts, are also presented in their own chart. + + \item[Q2D Histogram] A display of histogram buckets for the Q to D times + -- basically, from where an IO enters the block IO layer for a given + device, and when it is dispatched. The buckets are arranged via the + time in seconds, as in: + +\begin{verbatim} +==================== Q2D Histogram ==================== + + DEV | <.005 <.010 <.025 <.050 <.075 <.100 <.250 <.500 < 1.0 >=1.0 + --------- | ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== + ( 66, 80) | 61.2 7.9 12.1 7.9 3.0 1.4 1.5 0.2 0.0 4.6 + ( 65,192) | 42.3 5.0 8.7 30.0 8.9 3.0 1.8 0.1 0.0 0.1 + ( 65,128) | 34.3 5.3 8.9 32.0 9.7 3.7 5.3 0.6 0.0 0.1 +... + ( 65, 64) | 59.9 4.2 6.0 24.6 4.2 0.8 0.1 0.0 0.0 0.1 + ( 66, 64) | 62.6 8.1 12.7 7.9 2.4 0.6 0.1 0.0 0.0 5.4 +========== | ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== + AVG | 52.9 6.2 10.0 20.1 5.3 1.7 1.4 0.2 0.0 2.1 +\end{verbatim} + \end{description} \newpage\section{\label{sec:data-files}Data Files Output} diff --git a/btt/globals.h b/btt/globals.h index 5a6db04..4e8edc6 100644 --- a/btt/globals.h +++ b/btt/globals.h @@ -159,6 +159,7 @@ struct d_info { struct region_info regions; struct devmap *map; void *q2q_handle, *seek_handle, *bno_dump_handle, *unplug_hist_handle; + void *q2d_priv; FILE *d2c_ofp, *q2c_ofp; struct avgs_info avgs; struct stats stats, all_stats; @@ -296,6 +297,16 @@ void bno_dump_exit(void *param); void bno_dump_add(void *handle, struct io *iop); void bno_dump_clean(void); +/* q2d.c */ +void q2d_histo_add(void *priv, __u64 q2d); +void *q2d_init(void); +void q2d_release(void *priv); +void q2d_display_header(FILE *fp); +void q2d_display_dashes(FILE *fp); +void q2d_display(FILE *fp, void *priv); +int q2d_ok(void *priv); +void q2d_acc(void *a1, void *a2); + /* seek.c */ void *seeki_init(char *str); void seeki_exit(void *param); diff --git a/btt/output.c b/btt/output.c index ebfd3d8..787de70 100644 --- a/btt/output.c +++ b/btt/output.c @@ -133,6 +133,49 @@ void output_dip_avg(FILE *ofp, char *hdr, ai_dip_t (*func)(struct d_info *)) fprintf(ofp, "\n"); } +struct __q2d { + FILE *ofp; + void *q2d_all; + int n; +}; +void __output_q2d_histo(struct d_info *dip, void *arg) +{ + struct __q2d *q2dp = arg; + + if (q2d_ok(dip->q2d_priv)) { + char scratch[15]; + FILE *ofp = q2dp->ofp; + + fprintf(q2dp->ofp, "%10s | ", make_dev_hdr(scratch, 15, dip)); + q2d_display(ofp, dip->q2d_priv); + q2d_acc(q2dp->q2d_all, dip->q2d_priv); + q2dp->n++; + } +} + +void output_q2d_histo(FILE *ofp) +{ + struct __q2d __q2d = { + .ofp = ofp, + .q2d_all = q2d_init(), + .n = 0 + }; + + fprintf(ofp, "%10s | ", "DEV"); + q2d_display_header(ofp); + fprintf(ofp, "--------- | "); + q2d_display_dashes(ofp); + dip_foreach_out(__output_q2d_histo, &__q2d); + + if (__q2d.n) { + fprintf(ofp, "========== | "); + q2d_display_dashes(ofp); + fprintf(ofp, "%10s | ", "AVG"); + q2d_display(ofp, __q2d.q2d_all); + fprintf(ofp, "\n"); + } +} + int n_merges = 0; struct { unsigned long long nq, nd, blkmin, blkmax, total; @@ -648,6 +691,11 @@ int output_avgs(FILE *ofp) output_histos(); + if (output_all_data) { + output_section_hdr(ofp, "Q2D Histogram"); + output_q2d_histo(ofp); + } + return 0; } diff --git a/btt/q2d.c b/btt/q2d.c new file mode 100644 index 0000000..ae61e20 --- /dev/null +++ b/btt/q2d.c @@ -0,0 +1,121 @@ +/* + * blktrace output analysis: generate a timeline & gather statistics + * + * (C) Copyright 2007 Hewlett-Packard Development Company, L.P. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include +#include +#include + +#include "globals.h" + +#define Q2D_MAX_HISTO 9 +struct q2d_info { + unsigned long nhistos; + unsigned long histos[Q2D_MAX_HISTO + 1]; +}; + +void q2d_histo_add(void *priv, __u64 q2d_in) +{ + int index; + struct q2d_info *q2dp = priv; + double q2d = BIT_TIME(q2d_in); + long msec = (long)(q2d / 0.001); + + switch (msec) { + default: index = 9; break; + case 500 ... 999: index = 8; break; + case 250 ... 499: index = 7; break; + case 100 ... 249: index = 6; break; + case 75 ... 99: index = 5; break; + case 50 ... 74: index = 4; break; + case 25 ... 49: index = 3; break; + case 10 ... 24: index = 2; break; + case 5 ... 9: index = 1; break; + case 0 ... 4: index = 0; break; + } + + q2dp->histos[index]++; + q2dp->nhistos++; +} + +void *q2d_init(void) +{ + struct q2d_info *q2dp = malloc(sizeof(*q2dp)); + + return memset(q2dp, 0, sizeof(*q2dp)); +} + +void q2d_release(void *priv) +{ + free(priv); +} + +void q2d_display_header(FILE *fp) +{ + fprintf(fp, "%5s ", "<.005"); + fprintf(fp, "%5s ", "<.010"); + fprintf(fp, "%5s ", "<.025"); + fprintf(fp, "%5s ", "<.050"); + fprintf(fp, "%5s ", "<.075"); + fprintf(fp, "%5s ", "<.100"); + fprintf(fp, "%5s ", "<.250"); + fprintf(fp, "%5s ", "<.500"); + fprintf(fp, "%5s ", "< 1.0"); + fprintf(fp, "%5s ", ">=1.0\n"); +} + +void q2d_display_dashes(FILE *fp) +{ + int i; + + for (i = 0; i <= Q2D_MAX_HISTO; i++) + fprintf(fp, "===== "); + fprintf(fp, "\n"); +} + +void q2d_display(FILE *fp, void *priv) +{ + int i; + struct q2d_info *q2dp = priv; + double nh = (double)q2dp->nhistos; + + for (i = 0; i <= Q2D_MAX_HISTO; i++) { + double p = 100.0 * (double)q2dp->histos[i] / nh; + fprintf(fp, "%5.1lf ", p); + } + fprintf(fp, "\n"); +} + +int q2d_ok(void *priv) +{ + struct q2d_info *q2dp = priv; + + return q2dp && q2dp->nhistos > 0; +} + +void q2d_acc(void *a1, void *a2) +{ + int i; + struct q2d_info *ap = a1; + struct q2d_info *tp = a2; + + for (i = 0; i <= Q2D_MAX_HISTO; i++) + ap->histos[i] += tp->histos[i]; + ap->nhistos += tp->nhistos; +} diff --git a/btt/trace_issue.c b/btt/trace_issue.c index fd7ea49..418afd0 100644 --- a/btt/trace_issue.c +++ b/btt/trace_issue.c @@ -46,6 +46,10 @@ static void handle_issue(struct io *d_iop) q_iop->d_time = d_iop->t.time; q_iop->d_sec = d_iop->t.sector; q_iop->d_nsec = t_sec(&d_iop->t); + + if (output_all_data) + q2d_histo_add(q_iop->dip->q2d_priv, + d_iop->t.time - q_iop->t.time); } assert(d_iop->bytes_left == 0); -- 2.25.1