diff options
author | Martin Peschke <mp3@de.ibm.com> | 2008-10-16 07:48:25 +0200 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-10-16 07:48:25 +0200 |
commit | cc19ddd696e8931a969e943523e1dcf7a11ffe79 (patch) | |
tree | 24fad07f2492c5dda6a097b015073037232a728b /stats.h | |
parent | abf63eafd11e42e0f065e56fc4773e6854087d41 (diff) | |
download | blktrace-cc19ddd696e8931a969e943523e1dcf7a11ffe79.tar.gz blktrace-cc19ddd696e8931a969e943523e1dcf7a11ffe79.tar.bz2 |
blkiomon: I/O monitor
blkiomon periodicaly generates per devive request size and request latency
statistics from blktrace data. It provides histograms as well as data that
can be used to calculate min, max, average and variance. For this purpose,
it consumes D and C traces read from stdin.
There are options for binary output and human-readable output to files and
stdout. Output to a message queue is supported as well.
#blktrace /dev/sdw -a issue -a complete -w 200 -o - | blkiomon -I 8 -h -
time: Tue Sep 30 17:39:25 2008
device: 65,96
requests: read 62, write 40, bidir: 0
sizes: num 102, min 4096, max 430080, sum 13312000, squ 3102442782720,
avg 130509.8, var 13383296793.3
d2c: num 102, min 393, max 14261, sum 359441, squ 2830211755, avg 3523.9,
var 15329081.8
sizes histogram (in kB):
0: 0 1024: 0 2048: 0 4096: 6
8192: 0 16384: 15 32768: 4 65536: 24
131072: 11 262144: 30 524288: 12 1048576: 0
2097152: 0 4194304: 0 8388608: 0 > 8388608: 0
d2c histogram (in usec):
0: 0 8: 0 16: 0 32: 0
64: 0 128: 0 256: 0 512: 13
1024: 21 2048: 27 4096: 14 8192: 8
16384: 19 32768: 0 65536: 0 131072: 0
262144: 0 524288: 0 1048576: 0 2097152: 0
4194304: 0 8388608: 0 16777216: 0 33554432: 0
>33554432: 0
time: Tue Sep 30 17:39:33 2008
device: 65,96
requests: read 312, write 47, bidir: 0
sizes: num 359, min 4096, max 430080, sum 13197312, squ 1575816790016,
avg 36761.3, var 3038067547.5
d2c: num 359, min 294, max 9211, sum 387134, squ 1262489694, avg 1078.4,
var 2353807.5
sizes histogram (in kB):
0: 0 1024: 0 2048: 0 4096: 32
8192: 17 16384: 133 32768: 87 65536: 59
131072: 9 262144: 18 524288: 4 1048576: 0
2097152: 0 4194304: 0 8388608: 0 > 8388608: 0
d2c histogram (in usec):
0: 0 8: 0 16: 0 32: 0
64: 0 128: 0 256: 0 512: 129
1024: 164 2048: 33 4096: 15 8192: 13
16384: 5 32768: 0 65536: 0 131072: 0
262144: 0 524288: 0 1048576: 0 2097152: 0
4194304: 0 8388608: 0 16777216: 0 33554432: 0
>33554432: 0
Signed-off-by: Martin Peschke <mp3@de.ibm.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'stats.h')
-rw-r--r-- | stats.h | 155 |
1 files changed, 155 insertions, 0 deletions
@@ -0,0 +1,155 @@ +/* + * Copyright IBM Corp. 2008 + * + * Author(s): Martin Peschke <mp3@de.ibm.com> + * Stefan Raspl <stefan.raspl@de.ibm.com> + * + * 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 + */ + +#ifndef STATS_H +#define STATS_H + +#include <linux/types.h> +#include "endian.h" + +struct minmax { + __u64 min; + __u64 max; + __u64 sum; + __u64 sos; + __u64 num; +}; + +static inline void minmax_init(struct minmax *mm) +{ + mm->min = -1ULL; + mm->max = 0; + mm->sum = 0; + mm->sos = 0; + mm->num = 0; +} + +static inline void minmax_account(struct minmax *mm, __u64 value) +{ + mm->sum += value; + mm->sos += value * value; + if (value < mm->min) + mm->min = value; + if (value > mm->max) + mm->max = value; + mm->num++; +} + +static inline void minmax_merge(struct minmax *dst, struct minmax *src) +{ + dst->sum += src->sum; + dst->sos += src->sos; + if (src->min < dst->min) + dst->min = src->min; + if (src->max > dst->max) + dst->max = src->max; + dst->num += src->num; +} + +static inline void minmax_to_be(struct minmax *mm) +{ + mm->sum = cpu_to_be64(mm->sum); + mm->sos = cpu_to_be64(mm->sos); + mm->min = cpu_to_be64(mm->min); + mm->max = cpu_to_be64(mm->max); + mm->num = cpu_to_be64(mm->num); +} + +static inline double minmax_avg(struct minmax *mm) +{ + return (mm->sum / (double)mm->num); +} + +static inline double minmax_var(struct minmax *mm) +{ + double num = (double)mm->num; + + return ((mm->sos - ((mm->sum * mm->sum) / num)) / num); +} + +static inline int minmax_print(FILE *fp, const char *s, struct minmax *mm) +{ + return fprintf(fp, "%s: num %Ld, min %Ld, max %Ld, sum %Ld, squ %Ld, " + "avg %.1f, var %.1f\n", s, (unsigned long long)mm->num, + (unsigned long long)mm->min, (unsigned long long)mm->max, + (unsigned long long)mm->sum, (unsigned long long)mm->sos, + minmax_avg(mm), minmax_var(mm)); +} + +struct histlog2 { + int first; + int delta; + int num; +}; + +static inline __u64 histlog2_upper_limit(int index, struct histlog2 *h) +{ + return h->first + (index ? h->delta << (index - 1) : 0); +} + +static inline int histlog2_index(__u64 val, struct histlog2 *h) +{ + int i; + + for (i = 0; i < (h->num - 1) && val > histlog2_upper_limit(i, h); i++); + return i; +} + +static inline void histlog2_account(__u32 *bucket, __u32 val, + struct histlog2 *h) +{ + int index = histlog2_index(val, h); + bucket[index]++; +} + +static inline void histlog2_merge(struct histlog2 *h, __u32 *dst, __u32 *src) +{ + int i; + + for (i = 0; i < h->num - 1; i++) + dst[i] += src[i]; +} + +static inline void histlog2_to_be(__u32 a[], struct histlog2 *h) +{ + int i; + + for (i = 0; i < h->num - 1; i++) + a[i] = cpu_to_be32(a[i]); +} + +static inline void histlog2_print(FILE *fp, const char *s, __u32 a[], + struct histlog2 *h) +{ + int i; + + fprintf(fp, "%s:\n", s); + for (i = 0; i < h->num - 1; i++) { + fprintf(fp, " %10ld:%6d", + (unsigned long)(histlog2_upper_limit(i, h)), a[i]); + if (!((i + 1) % 4)) + fprintf(fp, "\n"); + } + fprintf(fp, " >%8ld:%6d\n", + (unsigned long)(histlog2_upper_limit(i - 1, h)), a[i]); +} + +#endif |