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