-
Notifications
You must be signed in to change notification settings - Fork 2
/
stat.h
203 lines (186 loc) · 6.43 KB
/
stat.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#ifndef FIO_STAT_H
#define FIO_STAT_H
struct group_run_stats {
uint64_t max_run[DDIR_RWDIR_CNT], min_run[DDIR_RWDIR_CNT];
uint64_t max_bw[DDIR_RWDIR_CNT], min_bw[DDIR_RWDIR_CNT];
uint64_t io_kb[DDIR_RWDIR_CNT];
uint64_t agg[DDIR_RWDIR_CNT];
uint32_t kb_base;
uint32_t groupid;
};
/*
* How many depth levels to log
*/
#define FIO_IO_U_MAP_NR 7
#define FIO_IO_U_LAT_U_NR 10
#define FIO_IO_U_LAT_M_NR 12
/*
* Aggregate clat samples to report percentile(s) of them.
*
* EXECUTIVE SUMMARY
*
* FIO_IO_U_PLAT_BITS determines the maximum statistical error on the
* value of resulting percentiles. The error will be approximately
* 1/2^(FIO_IO_U_PLAT_BITS+1) of the value.
*
* FIO_IO_U_PLAT_GROUP_NR and FIO_IO_U_PLAT_BITS determine the maximum
* range being tracked for latency samples. The maximum value tracked
* accurately will be 2^(GROUP_NR + PLAT_BITS -1) microseconds.
*
* FIO_IO_U_PLAT_GROUP_NR and FIO_IO_U_PLAT_BITS determine the memory
* requirement of storing those aggregate counts. The memory used will
* be (FIO_IO_U_PLAT_GROUP_NR * 2^FIO_IO_U_PLAT_BITS) * sizeof(int)
* bytes.
*
* FIO_IO_U_PLAT_NR is the total number of buckets.
*
* DETAILS
*
* Suppose the clat varies from 0 to 999 (usec), the straightforward
* method is to keep an array of (999 + 1) buckets, in which a counter
* keeps the count of samples which fall in the bucket, e.g.,
* {[0],[1],...,[999]}. However this consumes a huge amount of space,
* and can be avoided if an approximation is acceptable.
*
* One such method is to let the range of the bucket to be greater
* than one. This method has low accuracy when the value is small. For
* example, let the buckets be {[0,99],[100,199],...,[900,999]}, and
* the represented value of each bucket be the mean of the range. Then
* a value 0 has an round-off error of 49.5. To improve on this, we
* use buckets with non-uniform ranges, while bounding the error of
* each bucket within a ratio of the sample value. A simple example
* would be when error_bound = 0.005, buckets are {
* {[0],[1],...,[99]}, {[100,101],[102,103],...,[198,199]},..,
* {[900,909],[910,919]...} }. The total range is partitioned into
* groups with different ranges, then buckets with uniform ranges. An
* upper bound of the error is (range_of_bucket/2)/value_of_bucket
*
* For better efficiency, we implement this using base two. We group
* samples by their Most Significant Bit (MSB), extract the next M bit
* of them as an index within the group, and discard the rest of the
* bits.
*
* E.g., assume a sample 'x' whose MSB is bit n (starting from bit 0),
* and use M bit for indexing
*
* | n | M bits | bit (n-M-1) ... bit 0 |
*
* Because x is at least 2^n, and bit 0 to bit (n-M-1) is at most
* (2^(n-M) - 1), discarding bit 0 to (n-M-1) makes the round-off
* error
*
* 2^(n-M)-1 2^(n-M) 1
* e <= --------- <= ------- = ---
* 2^n 2^n 2^M
*
* Furthermore, we use "mean" of the range to represent the bucket,
* the error e can be lowered by half to 1 / 2^(M+1). By using M bits
* as the index, each group must contains 2^M buckets.
*
* E.g. Let M (FIO_IO_U_PLAT_BITS) be 6
* Error bound is 1/2^(6+1) = 0.0078125 (< 1%)
*
* Group MSB #discarded range of #buckets
* error_bits value
* ----------------------------------------------------------------
* 0* 0~5 0 [0,63] 64
* 1* 6 0 [64,127] 64
* 2 7 1 [128,255] 64
* 3 8 2 [256,511] 64
* 4 9 3 [512,1023] 64
* ... ... ... [...,...] ...
* 18 23 17 [8838608,+inf]** 64
*
* * Special cases: when n < (M-1) or when n == (M-1), in both cases,
* the value cannot be rounded off. Use all bits of the sample as
* index.
*
* ** If a sample's MSB is greater than 23, it will be counted as 23.
*/
#define FIO_IO_U_PLAT_BITS 6
#define FIO_IO_U_PLAT_VAL (1 << FIO_IO_U_PLAT_BITS)
#define FIO_IO_U_PLAT_GROUP_NR 19
#define FIO_IO_U_PLAT_NR (FIO_IO_U_PLAT_GROUP_NR * FIO_IO_U_PLAT_VAL)
#define FIO_IO_U_LIST_MAX_LEN 20 /* The size of the default and user-specified
list of percentiles */
#define MAX_PATTERN_SIZE 512
#define FIO_JOBNAME_SIZE 128
#define FIO_VERROR_SIZE 128
struct thread_stat {
char name[FIO_JOBNAME_SIZE];
char verror[FIO_VERROR_SIZE];
uint32_t error;
uint32_t groupid;
uint32_t pid;
char description[FIO_JOBNAME_SIZE];
uint32_t members;
/*
* bandwidth and latency stats
*/
struct io_stat clat_stat[DDIR_RWDIR_CNT]; /* completion latency */
struct io_stat slat_stat[DDIR_RWDIR_CNT]; /* submission latency */
struct io_stat lat_stat[DDIR_RWDIR_CNT]; /* total latency */
struct io_stat bw_stat[DDIR_RWDIR_CNT]; /* bandwidth stats */
struct io_stat iops_stat[DDIR_RWDIR_CNT]; /* IOPS stats */
/*
* fio system usage accounting
*/
uint64_t usr_time;
uint64_t sys_time;
uint64_t ctx;
uint64_t minf, majf;
/*
* IO depth and latency stats
*/
uint64_t clat_percentiles;
fio_fp64_t percentile_list[FIO_IO_U_LIST_MAX_LEN];
uint32_t io_u_map[FIO_IO_U_MAP_NR];
uint32_t io_u_submit[FIO_IO_U_MAP_NR];
uint32_t io_u_complete[FIO_IO_U_MAP_NR];
uint32_t io_u_lat_u[FIO_IO_U_LAT_U_NR];
uint32_t io_u_lat_m[FIO_IO_U_LAT_M_NR];
uint32_t io_u_plat[DDIR_RWDIR_CNT][FIO_IO_U_PLAT_NR];
uint64_t total_io_u[3];
uint64_t short_io_u[3];
uint64_t total_submit;
uint64_t total_complete;
uint64_t io_bytes[DDIR_RWDIR_CNT];
uint64_t runtime[DDIR_RWDIR_CNT];
uint64_t total_run_time;
/*
* IO Error related stats
*/
uint16_t continue_on_error;
uint64_t total_err_count;
uint32_t first_error;
uint32_t kb_base;
};
struct jobs_eta {
uint32_t nr_running;
uint32_t nr_ramp;
uint32_t nr_pending;
uint32_t files_open;
uint32_t m_rate, t_rate;
uint32_t m_iops, t_iops;
uint32_t rate[DDIR_RWDIR_CNT];
uint32_t iops[DDIR_RWDIR_CNT];
uint64_t elapsed_sec;
uint64_t eta_sec;
uint32_t is_pow2;
/*
* Network 'copy' of run_str[]
*/
uint32_t nr_threads;
uint8_t run_str[0];
};
extern void show_thread_status(struct thread_stat *ts, struct group_run_stats *rs);
extern void show_group_stats(struct group_run_stats *rs);
extern int calc_thread_status(struct jobs_eta *je, int force);
extern void display_thread_status(struct jobs_eta *je);
extern void show_run_stats(void);
extern void show_running_run_stats(void);
extern void sum_thread_stats(struct thread_stat *dst, struct thread_stat *src, int nr);
extern void sum_group_stats(struct group_run_stats *dst, struct group_run_stats *src);
extern void init_thread_stat(struct thread_stat *ts);
extern void init_group_run_stat(struct group_run_stats *gs);
#endif