2 // Copyright (c) 2010-2017 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
17 #ifndef _HANDLE_LAT_H_
18 #define _HANDLE_LAT_H_
24 #include "task_base.h"
27 #define LATENCY_ACCURACY 1
30 uint64_t tot_all_pkts;
35 unsigned __int128 var_lat; /* variance */
36 uint64_t accuracy_limit_tsc;
38 uint64_t max_lat_error;
39 uint64_t min_lat_error;
40 uint64_t tot_lat_error;
41 unsigned __int128 var_lat_error;
43 uint64_t buckets[128];
45 uint64_t lost_packets;
48 static struct time_unit lat_test_get_accuracy_limit(struct lat_test *lat_test)
50 return tsc_to_time_unit(lat_test->accuracy_limit_tsc);
53 static struct time_unit_err lat_test_get_avg(struct lat_test *lat_test)
58 tsc = lat_test->tot_lat/lat_test->tot_pkts;
59 tsc_error = lat_test->tot_lat_error/lat_test->tot_pkts;
61 struct time_unit_err ret = {
62 .time = tsc_to_time_unit(tsc),
63 .error = tsc_to_time_unit(tsc_error),
69 static struct time_unit_err lat_test_get_min(struct lat_test *lat_test)
71 struct time_unit_err ret = {
72 .time = tsc_to_time_unit(lat_test->min_lat),
73 .error = tsc_to_time_unit(lat_test->min_lat_error),
79 static struct time_unit_err lat_test_get_max(struct lat_test *lat_test)
81 struct time_unit_err ret = {
82 .time = tsc_to_time_unit(lat_test->max_lat),
83 .error = tsc_to_time_unit(lat_test->max_lat_error),
89 static struct time_unit_err lat_test_get_stddev(struct lat_test *lat_test)
91 unsigned __int128 avg_tsc = lat_test->tot_lat/lat_test->tot_pkts;
92 unsigned __int128 avg_tsc_squared = avg_tsc * avg_tsc;
93 unsigned __int128 avg_squares_tsc = lat_test->var_lat/lat_test->tot_pkts;
95 /* The assumption is that variance fits into 64 bits, meaning
96 that standard deviation fits into 32 bits. In other words,
97 the assumption is that the standard deviation is not more
98 than approximately 1 second. */
99 uint64_t var_tsc = avg_squares_tsc - avg_tsc_squared;
100 uint64_t stddev_tsc = sqrt(var_tsc);
102 unsigned __int128 avg_tsc_error = lat_test->tot_lat_error / lat_test->tot_pkts;
103 unsigned __int128 avg_tsc_squared_error = 2 * avg_tsc * avg_tsc_error + avg_tsc_error * avg_tsc_error;
104 unsigned __int128 avg_squares_tsc_error = lat_test->var_lat_error / lat_test->tot_pkts;
106 uint64_t var_tsc_error = avg_squares_tsc_error + avg_tsc_squared_error;
108 /* sqrt(a+-b) = sqrt(a) +- (-sqrt(a) + sqrt(a + b)) */
110 uint64_t stddev_tsc_error = - stddev_tsc + sqrt(var_tsc + var_tsc_error);
112 struct time_unit_err ret = {
113 .time = tsc_to_time_unit(stddev_tsc),
114 .error = tsc_to_time_unit(stddev_tsc_error),
120 static void _lat_test_histogram_combine(struct lat_test *dst, struct lat_test *src)
122 for (size_t i = 0; i < sizeof(dst->buckets)/sizeof(dst->buckets[0]); ++i)
123 dst->buckets[i] += src->buckets[i];
126 static void lat_test_combine(struct lat_test *dst, struct lat_test *src)
128 dst->tot_all_pkts += src->tot_all_pkts;
130 dst->tot_pkts += src->tot_pkts;
132 dst->tot_lat += src->tot_lat;
133 dst->tot_lat_error += src->tot_lat_error;
135 /* (a +- b)^2 = a^2 +- (2ab + b^2) */
136 dst->var_lat += src->var_lat;
137 dst->var_lat_error += src->var_lat_error;
139 if (src->max_lat > dst->max_lat) {
140 dst->max_lat = src->max_lat;
141 dst->max_lat_error = src->max_lat_error;
143 if (src->min_lat < dst->min_lat) {
144 dst->min_lat = src->min_lat;
145 dst->min_lat_error = src->min_lat_error;
148 if (src->accuracy_limit_tsc > dst->accuracy_limit_tsc)
149 dst->accuracy_limit_tsc = src->accuracy_limit_tsc;
150 dst->lost_packets += src->lost_packets;
152 #ifdef LATENCY_HISTOGRAM
153 _lat_test_histogram_combine(dst, src);
157 static void lat_test_reset(struct lat_test *lat_test)
159 lat_test->tot_all_pkts = 0;
160 lat_test->tot_pkts = 0;
161 lat_test->max_lat = 0;
162 lat_test->min_lat = -1;
163 lat_test->tot_lat = 0;
164 lat_test->var_lat = 0;
165 lat_test->max_lat_error = 0;
166 lat_test->min_lat_error = 0;
167 lat_test->tot_lat_error = 0;
168 lat_test->var_lat_error = 0;
169 lat_test->accuracy_limit_tsc = 0;
171 lat_test->lost_packets = 0;
173 memset(lat_test->buckets, 0, sizeof(lat_test->buckets));
176 static void lat_test_copy(struct lat_test *dst, struct lat_test *src)
178 if (src->tot_all_pkts)
179 memcpy(dst, src, sizeof(struct lat_test));
184 struct lat_test *task_lat_get_latency_meassurement(struct task_lat *task);
185 void task_lat_use_other_latency_meassurement(struct task_lat *task);
186 void task_lat_set_accuracy_limit(struct task_lat *task, uint32_t accuracy_limit_nsec);
188 #endif /* _HANDLE_LAT_H_ */