4a82a8db3609e8f641956bf3e0b20c66ea1f81d3
2 +--------------------------------------------------------------------+
3 | libmemcached - C/C++ Client Library for memcached |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted under the terms of the BSD license. |
7 | You should have received a copy of the license in a bundled file |
8 | named LICENSE; in case you did not receive a copy you can review |
9 | the terms online at: https://opensource.org/licenses/BSD-3-Clause |
10 +--------------------------------------------------------------------+
11 | Copyright (c) 2006-2014 Brian Aker https://datadifferential.com/ |
12 | Copyright (c) 2020 Michael Wallner <mike@php.net> |
13 +--------------------------------------------------------------------+
16 #include "mem_config.h"
21 #define array_size(x) (sizeof(x) / sizeof((x)[0]))
23 static int ms_local_log2(uint64_t value
);
24 static uint64_t ms_get_events(ms_stat_t
*stat
);
27 * get the index of local log2 array
31 * @return return the index of local log2 array
33 static int ms_local_log2(uint64_t value
) {
36 while (result
<= 63 && ((uint64_t) 1 << result
) < value
) {
44 * initialize statistic structure
46 * @param stat, pointer of the statistic structure
47 * @param name, name of the statistic
49 void ms_init_stats(ms_stat_t
*stat
, const char *name
) {
50 memset(stat
, 0, sizeof(*stat
));
52 stat
->name
= (char *) name
;
53 stat
->min_time
= (uint64_t) -1;
55 stat
->period_min_time
= (uint64_t) -1;
56 stat
->period_max_time
= 0;
57 stat
->log_product
= 0;
59 stat
->pre_total_time
= 0;
61 stat
->pre_squares
= 0;
63 stat
->pre_log_product
= 0;
65 stat
->pre_get_miss
= 0;
71 * @param stat, pointer of the statistic structure
72 * @param total_time, response time of the command
73 * @param get_miss, whether it gets miss
75 void ms_record_event(ms_stat_t
*stat
, uint64_t total_time
, int get_miss
) {
76 stat
->total_time
+= total_time
;
78 if (total_time
< stat
->min_time
) {
79 stat
->min_time
= total_time
;
82 if (total_time
> stat
->max_time
) {
83 stat
->max_time
= total_time
;
86 if (total_time
< stat
->period_min_time
) {
87 stat
->period_min_time
= total_time
;
90 if (total_time
> stat
->period_max_time
) {
91 stat
->period_max_time
= total_time
;
98 stat
->dist
[ms_local_log2(total_time
)]++;
99 stat
->squares
+= (double) (total_time
* total_time
);
102 stat
->log_product
+= log((double) total_time
);
104 } /* ms_record_event */
107 * get the events count
109 * @param stat, pointer of the statistic structure
111 * @return total events recorded
114 __attribute__ (( no_sanitize_thread
, no_sanitize("thread")))
116 static uint64_t ms_get_events(ms_stat_t
*stat
) {
119 for (uint32_t i
= 0; i
< array_size(stat
->dist
); i
++) {
120 events
+= stat
->dist
[i
];
124 } /* ms_get_events */
127 * dump the statistics
129 * @param stat, pointer of the statistic structure
131 void ms_dump_stats(ms_stat_t
*stat
) {
133 int max_non_zero
= 0;
134 int min_non_zero
= 0;
137 for (uint32_t i
= 0; i
< array_size(stat
->dist
); i
++) {
138 events
+= stat
->dist
[i
];
140 max_non_zero
= (int) i
;
147 average
= (double) (stat
->total_time
/ events
);
149 printf("%s Statistics (%lld events)\n", stat
->name
, (long long) events
);
150 printf(" Min: %8lld\n", (long long) stat
->min_time
);
151 printf(" Max: %8lld\n", (long long) stat
->max_time
);
152 printf(" Avg: %8lld\n", (long long) (stat
->total_time
/ events
));
153 printf(" Geo: %8.2lf\n", exp(stat
->log_product
/ (double) events
));
156 printf(" Std: %8.2lf\n",
157 sqrt((stat
->squares
- (double) events
* average
* average
) / ((double) events
- 1)));
159 printf(" Log2 Dist:");
161 for (int i
= 0; i
<= max_non_zero
- 4; i
+= 4) {
162 if ((stat
->dist
[i
+ 0]) || (stat
->dist
[i
+ 1]) || (stat
->dist
[i
+ 2])
163 || (stat
->dist
[i
+ 3]))
170 for (int i
= min_non_zero
; i
<= max_non_zero
; i
++) {
172 printf("\n %2d:", (int) i
);
174 printf(" %6" PRIu64
, stat
->dist
[i
]);
178 } /* ms_dump_stats */
181 * dump the format statistics
183 * @param stat, pointer of the statistic structure
184 * @param run_time, the total run time
185 * @param freq, statistic frequency
186 * @param obj_size, average object size
189 __attribute__ (( no_sanitize_thread
, no_sanitize("thread")))
191 void ms_dump_format_stats(ms_stat_t
*stat
, int run_time
, 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 double period_average
= 0;
200 uint64_t period_tps
= 0;
201 double period_rate
= 0;
202 double period_std
= 0;
203 double period_log
= 0;
205 if ((events
= ms_get_events(stat
)) == 0) {
209 global_average
= (double) (stat
->total_time
/ events
);
210 global_tps
= events
/ (uint64_t) run_time
;
211 global_rate
= (double) events
* obj_size
/ 1024 / 1024 / run_time
;
212 global_std
= sqrt((stat
->squares
- (double) events
* global_average
* global_average
)
213 / (double) (events
- 1));
214 global_log
= exp(stat
->log_product
/ (double) events
);
216 uint64_t diff_time
= stat
->total_time
- stat
->pre_total_time
;
217 uint64_t diff_events
= events
- stat
->pre_events
;
218 if (diff_events
>= 1) {
219 period_average
= (double) (diff_time
/ diff_events
);
220 period_tps
= diff_events
/ (uint64_t) freq
;
221 period_rate
= (double) diff_events
* obj_size
/ 1024 / 1024 / freq
;
222 double diff_squares
= (double) stat
->squares
- (double) stat
->pre_squares
;
223 period_std
= sqrt((diff_squares
- (double) diff_events
* period_average
* period_average
)
224 / (double) (diff_events
- 1));
225 double diff_log_product
= stat
->log_product
- stat
->pre_log_product
;
226 period_log
= exp(diff_log_product
/ (double) diff_events
);
229 printf("%s Statistics\n", stat
->name
);
230 printf("%-8s %-8s %-12s %-12s %-10s %-10s %-8s %-10s %-10s %-10s %-10s\n", "Type", "Time(s)",
231 "Ops", "TPS(ops/s)", "Net(M/s)", "Get_miss", "Min(us)", "Max(us)", "Avg(us)", "Std_dev",
234 printf("%-8s %-8d %-12llu %-12lld %-10.1f %-10lld %-8lld %-10lld %-10lld %-10.2f %.2f\n",
235 "Period", freq
, (long long) diff_events
, (long long) period_tps
, global_rate
,
236 (long long) (stat
->get_miss
- stat
->pre_get_miss
), (long long) stat
->period_min_time
,
237 (long long) stat
->period_max_time
, (long long) period_average
, period_std
, period_log
);
239 printf("%-8s %-8d %-12llu %-12lld %-10.1f %-10lld %-8lld %-10lld %-10lld %-10.2f %.2f\n\n",
240 "Global", run_time
, (long long) events
, (long long) global_tps
, period_rate
,
241 (long long) stat
->get_miss
, (long long) stat
->min_time
, (long long) stat
->max_time
,
242 (long long) global_average
, global_std
, global_log
);
244 stat
->pre_events
= events
;
245 stat
->pre_squares
= (uint64_t) stat
->squares
;
246 stat
->pre_total_time
= stat
->total_time
;
247 stat
->pre_log_product
= stat
->log_product
;
248 stat
->period_min_time
= (uint64_t) -1;
249 stat
->period_max_time
= 0;
250 stat
->pre_get_miss
= stat
->get_miss
;
251 } /* ms_dump_format_stats */