-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathstats.c
148 lines (120 loc) · 4.15 KB
/
stats.c
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
//
// stats.c
//
// Author: David Meisner ([email protected])
//
#include "stats.h"
#include "loader.h"
#include <assert.h>
#include "worker.h"
pthread_mutex_t stats_lock = PTHREAD_MUTEX_INITIALIZER;
void addSample(struct stat* stat, float value) {
stat->s0 += 1.0;
stat->s1 += value;
stat->s2 += value*value;
stat->min = fmin(stat->min,value);
stat->max = fmax(stat->max,value);
if(value < .001){
int bin = (int)(value*10000000);
stat->micros[bin] += 1;
} else if( value < 5.0){
int bin = value * 10000.0;
assert(bin < 50001);
stat->millis[bin] += 1;
} else if (value < 999){
int bin = (int)value;
stat->fulls[bin] += 1;
} else {
int bin = (int)value/1000;
if (bin > 999){
bin = 999;
}
stat->fulls[bin] += 1;
}
}//End addAvgSample()
double getAvg(struct stat* stat) {
return (stat->s1/stat->s0);
}//End getAvg()
double getStdDev(struct stat* stat) {
return sqrt((stat->s0*stat->s2 - stat->s1*stat->s1)/(stat->s0*(stat->s0 - 1)));
}//End getStdDev()
//Should we exit because time has expired?
void checkExit(struct config* config) {
int runTime = config->run_time;
struct timeval currentTime;
gettimeofday(¤tTime, NULL);
double totalTime = currentTime.tv_sec - start_time.tv_sec + 1e-6*(currentTime.tv_sec - start_time.tv_sec);
if(totalTime >= runTime && runTime >0) {
printf("Ran for %f, exiting\n", totalTime);
exit(0);
}
}//End checkExit()
double findQuantile(struct stat* stat, double quantile) {
//Find the 95th-percentile
int nTillQuantile = global_stats.response_time.s0 * quantile;
int count = 0;
int i;
for( i = 0; i < 10000; i++) {
count += stat->micros[i];
if( count >= nTillQuantile ){
double quantile = (i+1) * .0000001;
return quantile;
}
}//End for i
for( i = 0; i < 50000; i++) {
count += stat->millis[i];
if( count >= nTillQuantile ){
double quantile = (i+1) * .0001;
return quantile;
}
}//End for i
printf("count %d\n", count);
for( i = 0; i < 1000; i++) {
count += stat->fulls[i];
if( count >= nTillQuantile ){
double quantile = i+1;
return quantile;
}
}//End for i
return 1000;
}//End findQuantile()
void printGlobalStats(struct config* config) {
pthread_mutex_lock(&stats_lock);
struct timeval currentTime;
gettimeofday(¤tTime, NULL);
double timeDiff = currentTime.tv_sec - global_stats.last_time.tv_sec + 1e-6*(currentTime.tv_usec - global_stats.last_time.tv_usec);
double rps = global_stats.requests/timeDiff;
double std = getStdDev(&global_stats.response_time);
double q90 = findQuantile(&global_stats.response_time, .90);
double q95 = findQuantile(&global_stats.response_time, .95);
double q99 = findQuantile(&global_stats.response_time, .99);
printf("%10s,%8s,%16s, %8s,%11s,%10s,%13s,%10s,%10s,%10s,%12s,%10s,%10s,%11s,%14s\n", "timeDiff", "rps", "requests", "gets", "sets", "hits", "misses", "avg_lat", "90th", "95th", "99th", "std", "min", "max", "avgGetSize");
printf("%10f, %9.1f, %10d, %10d, %10d, %10d, %10d, %10f, %10f, %10f, %10f, %10f, %10f, %10f, %10f\n",
timeDiff, rps, global_stats.requests, global_stats.gets, global_stats.sets, global_stats.hits, global_stats.misses,
1000*getAvg(&global_stats.response_time), 1000*q90, 1000*q95, 1000*q99, 1000*std, 1000*global_stats.response_time.min, 1000*global_stats.response_time.max, getAvg(&global_stats.get_size));
int i;
printf("Outstanding requests per worker:\n");
for(i=0; i<config->n_workers; i++){
printf("%d ", config->workers[i]->n_requests);
}
printf("\n");
//Reset stats
memset(&global_stats, 0, sizeof(struct memcached_stats));
global_stats.response_time.min = 1000000;
global_stats.last_time = currentTime;
checkExit(config);
pthread_mutex_unlock(&stats_lock);
}//End printGlobalStats()
//Print out statistics every second
void statsLoop(struct config* config) {
pthread_mutex_lock(&stats_lock);
gettimeofday(&start_time, NULL);
pthread_mutex_unlock(&stats_lock);
sleep(2);
printf("Stats:\n");
printf("-------------------------\n");
while(1) {
printGlobalStats(config);
sleep(config->stats_time);
}//End while()
}//End statisticsLoop()