3 * Author: Mingqiang Zhuang
5 * Created on March 25, 2009
7 * (c) Copyright 2009, Schooner Information Technology, Inc.
8 * http://www.schoonerinfotech.com/
13 #define array_size(x) (sizeof(x) / sizeof((x)[0]))
15 static int ms_local_log2(uint64_t value
);
16 static uint64_t ms_get_events(ms_stat_t
*stat
);
20 * get the index of local log2 array
24 * @return return the index of local log2 array
26 static int ms_local_log2(uint64_t value
)
30 while (result
<= 63 && ((uint64_t) 1 << result
) < value
) {
38 * initialize statistic structure
40 * @param stat, pointer of the statistic structure
41 * @param name, name of the statistic
43 void ms_init_stats(ms_stat_t
*stat
, const char *name
)
45 memset(stat
, 0, sizeof(*stat
));
47 stat
->name
= (char *)name
;
48 stat
->min_time
= (uint64_t) -1;
50 stat
->period_min_time
= (uint64_t) -1;
51 stat
->period_max_time
= 0;
52 stat
->log_product
= 0;
54 stat
->pre_total_time
= 0;
56 stat
->pre_squares
= 0;
58 stat
->pre_log_product
= 0;
60 stat
->pre_get_miss
= 0;
68 * @param stat, pointer of the statistic structure
69 * @param total_time, response time of the command
70 * @param get_miss, whether it gets miss
72 void ms_record_event(ms_stat_t
*stat
, uint64_t total_time
, int get_miss
)
74 stat
->total_time
+= total_time
;
76 if (total_time
< stat
->min_time
) {
77 stat
->min_time
= total_time
;
80 if (total_time
> stat
->max_time
) {
81 stat
->max_time
= total_time
;
84 if (total_time
< stat
->period_min_time
) {
85 stat
->period_min_time
= total_time
;
88 if (total_time
> stat
->period_max_time
) {
89 stat
->period_max_time
= total_time
;
96 stat
->dist
[ms_local_log2(total_time
)]++;
97 stat
->squares
+= (double)(total_time
* total_time
);
99 if (total_time
!= 0) {
100 stat
->log_product
+= log((double) total_time
);
107 * get the events count
109 * @param stat, pointer of the statistic structure
111 * @return total events recorded
113 static uint64_t ms_get_events(ms_stat_t
*stat
)
117 for (uint32_t i
= 0; i
< array_size(stat
->dist
); i
++) {
118 events
+= stat
->dist
[i
];
125 * dump the statistics
127 * @param stat, pointer of the statistic structure
129 void ms_dump_stats(ms_stat_t
*stat
)
132 int max_non_zero
= 0;
133 int min_non_zero
= 0;
136 for (uint32_t i
= 0; i
< array_size(stat
->dist
); i
++) {
137 events
+= stat
->dist
[i
];
138 if (stat
->dist
[i
] != 0) {
139 max_non_zero
= (int)i
;
146 average
= (double)(stat
->total_time
/ events
);
148 printf("%s Statistics (%lld events)\n", stat
->name
, (long long)events
);
149 printf(" Min: %8lld\n", (long long)stat
->min_time
);
150 printf(" Max: %8lld\n", (long long)stat
->max_time
);
151 printf(" Avg: %8lld\n", (long long)(stat
->total_time
/ events
));
152 printf(" Geo: %8.2lf\n", exp(stat
->log_product
/ (double)events
));
155 printf(" Std: %8.2lf\n",
156 sqrt((stat
->squares
- (double)events
* average
* average
) / ((double)events
- 1)));
158 printf(" Log2 Dist:");
160 for (int i
= 0; i
<= max_non_zero
- 4; i
+= 4) {
161 if (stat
->dist
[i
+ 0] != 0
162 || stat
->dist
[i
+ 1] != 0
163 || stat
->dist
[i
+ 2] != 0
164 || stat
->dist
[i
+ 3] != 0) {
170 for (int i
= min_non_zero
; i
<= max_non_zero
; i
++) {
172 printf("\n %2d:", (int) i
);
174 printf(" %6ld", stat
->dist
[i
]);
182 * dump the format statistics
184 * @param stat, pointer of the statistic structure
185 * @param run_time, the total run time
186 * @param freq, statistic frequency
187 * @param obj_size, average object size
189 void ms_dump_format_stats(ms_stat_t
*stat
, int run_time
,
190 int freq
, int obj_size
)
193 double global_average
= 0;
194 uint64_t global_tps
= 0;
195 double global_rate
= 0;
196 double global_std
= 0;
197 double global_log
= 0;
199 uint64_t diff_time
= 0;
200 uint64_t diff_events
= 0;
201 double diff_squares
= 0;
202 double diff_log_product
= 0;
203 double period_average
= 0;
204 uint64_t period_tps
= 0;
205 double period_rate
= 0;
206 double period_std
= 0;
207 double period_log
= 0;
209 if ((events
= ms_get_events(stat
)) == 0) {
213 global_average
= (double)(stat
->total_time
/ events
);
214 global_tps
= events
/ (uint64_t)run_time
;
215 global_rate
= (double)events
* obj_size
/ 1024 / 1024 / run_time
;
216 global_std
= sqrt((stat
->squares
- (double)events
* global_average
217 * global_average
) / (double)(events
- 1));
218 global_log
= exp(stat
->log_product
/ (double)events
);
220 diff_time
= stat
->total_time
- stat
->pre_total_time
;
221 diff_events
= events
- stat
->pre_events
;
222 if (diff_events
>= 1) {
223 period_average
= (double)(diff_time
/ diff_events
);
224 period_tps
= diff_events
/ (uint64_t)freq
;
225 period_rate
= (double)diff_events
* obj_size
/ 1024 / 1024 / freq
;
226 diff_squares
= (double)stat
->squares
- (double)stat
->pre_squares
;
227 period_std
= sqrt((diff_squares
- (double)diff_events
* period_average
228 * period_average
) / (double)(diff_events
- 1));
229 diff_log_product
= stat
->log_product
- stat
->pre_log_product
;
230 period_log
= exp(diff_log_product
/ (double)diff_events
);
233 printf("%s Statistics\n", stat
->name
);
234 printf("%-8s %-8s %-12s %-12s %-10s %-10s %-8s %-10s %-10s %-10s %-10s\n", "Type",
235 "Time(s)", "Ops", "TPS(ops/s)", "Net(M/s)", "Get_miss", "Min(us)", "Max(us)",
236 "Avg(us)", "Std_dev", "Geo_dist");
238 printf("%-8s %-8d %-12llu %-12lld %-10.1f %-10lld %-8lld %-10lld %-10lld %-10.2f %.2f\n",
239 "Period", freq
, (long long)diff_events
, (long long)period_tps
, global_rate
,
240 (long long)(stat
->get_miss
- stat
->pre_get_miss
),
241 (long long)stat
->period_min_time
, (long long)stat
->period_max_time
,
242 (long long)period_average
, period_std
, period_log
);
244 printf("%-8s %-8d %-12llu %-12lld %-10.1f %-10lld %-8lld %-10lld %-10lld %-10.2f %.2f\n\n",
245 "Global", run_time
, (long long)events
, (long long)global_tps
, period_rate
,
246 (long long)stat
->get_miss
, (long long)stat
->min_time
,
247 (long long)stat
->max_time
, (long long)global_average
,
248 global_std
, global_log
);
250 stat
->pre_events
= events
;
251 stat
->pre_squares
= (uint64_t)stat
->squares
;
252 stat
->pre_total_time
= stat
->total_time
;
253 stat
->pre_log_product
= stat
->log_product
;
254 stat
->period_min_time
= (uint64_t)-1;
255 stat
->period_max_time
= 0;
256 stat
->pre_get_miss
= stat
->get_miss
;