1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

added warmup phase to histogram for better selection of min/max (closes #12)

This commit is contained in:
Steffen Vogel 2017-05-05 22:26:34 +00:00
parent 49054eef9f
commit c711f0f1bc
6 changed files with 57 additions and 60 deletions

View file

@ -47,6 +47,8 @@ struct hist {
int length; /**< The number of buckets in #data. */
hist_cnt_t total; /**< Total number of counted values. */
hist_cnt_t warmup; /**< Number of values which are used during warmup phase. */
hist_cnt_t higher; /**< The number of values which are higher than #high. */
hist_cnt_t lower; /**< The number of values which are lower than #low. */
@ -56,7 +58,7 @@ struct hist {
};
/** Initialize struct hist with supplied values and allocate memory for buckets. */
int hist_init(struct hist *h, double start, double end, double resolution);
int hist_init(struct hist *h, int buckets, hist_cnt_t warmup);
/** Free the dynamically allocated memory. */
int hist_destroy(struct hist *h);

View file

@ -66,7 +66,7 @@ struct stats {
struct stats_delta *delta;
};
int stats_init(struct stats *s);
int stats_init(struct stats *s, int buckets, int warmup);
void stats_destroy(struct stats *s);

View file

@ -34,20 +34,12 @@
#define VAL(h, i) ((h)->low + (i) * (h)->resolution)
#define INDEX(h, v) round((v - (h)->low) / (h)->resolution)
int hist_init(struct hist *h, double low, double high, double resolution)
int hist_init(struct hist *h, int buckets, hist_cnt_t warmup)
{
h->low = low;
h->high = high;
h->resolution = resolution;
h->length = buckets;
h->warmup = warmup;
if (resolution > 0) {
h->length = (high - low) / resolution;
h->data = alloc(h->length * sizeof(hist_cnt_t));
}
else {
h->length = 0;
h->data = NULL;
}
h->data = buckets ? alloc(h->length * sizeof(hist_cnt_t)) : NULL;
hist_reset(h);
@ -66,8 +58,6 @@ int hist_destroy(struct hist *h)
void hist_put(struct hist *h, double value)
{
int idx = INDEX(h, value);
h->last = value;
/* Update min/max */
@ -76,13 +66,25 @@ void hist_put(struct hist *h, double value)
if (value < h->lowest)
h->lowest = value;
/* Check bounds and increment */
if (idx >= h->length)
h->higher++;
else if (idx < 0)
h->lower++;
else if (h->data != NULL)
h->data[idx]++;
if (h->total < h->warmup) {
}
else if (h->total == h->warmup) {
h->low = hist_mean(h) - 3 * hist_stddev(h);
h->high = hist_mean(h) + 3 * hist_stddev(h);
h->resolution = (h->high - h->low) / h->length;
}
else {
int idx = INDEX(h, value);
/* Check bounds and increment */
if (idx >= h->length)
h->higher++;
else if (idx < 0)
h->lower++;
else if (h->data != NULL)
h->data[idx]++;
}
h->total++;

View file

@ -34,6 +34,8 @@ struct stats_collect {
enum stats_format format;
int verbose;
int warmup;
int buckets;
FILE *output;
const char *uri;
@ -43,8 +45,6 @@ static int stats_collect_init(struct hook *h)
{
struct stats_collect *p = h->_vd;
stats_init(&p->stats);
/* Register statistic object to path.
*
* This allows the path code to update statistics. */
@ -54,6 +54,8 @@ static int stats_collect_init(struct hook *h)
/* Set default values */
p->format = STATS_FORMAT_HUMAN;
p->verbose = 0;
p->warmup = 500;
p->buckets = 20;
p->uri = NULL;
p->output = stdout;
@ -73,6 +75,8 @@ static int stats_collect_start(struct hook *h)
{
struct stats_collect *p = h->_vd;
stats_init(&p->stats, p->buckets, p->warmup);
if (p->uri) {
p->output = fopen(p->uri, "w+");
if (!p->output)
@ -129,6 +133,8 @@ static int stats_collect_parse(struct hook *h, config_setting_t *cfg)
}
config_setting_lookup_int(cfg, "verbose", &p->verbose);
config_setting_lookup_int(cfg, "warmup", &p->warmup);
config_setting_lookup_int(cfg, "buckets", &p->buckets);
config_setting_lookup_string(cfg, "output", &p->uri);
return 0;
@ -164,4 +170,4 @@ static struct plugin p = {
REGISTER_PLUGIN(&p)
/** @} */
/** @} */

View file

@ -33,26 +33,19 @@ static struct stats_desc {
const char *name;
const char *unit;
const char *desc;
struct {
double min;
double max;
double resolution;
} hist;
int hist_buckets;
} stats_table[] = {
{ "skipped", "samples", "skipped samples by hooks", {0, 0, -1, }},
{ "reorderd", "samples", "reordered samples", {0, 20, 1, }},
{ "gap_sequence", "samples", "sequence number displacement of received messages", {-10, 10, 20, }},
{ "gap_sample", "seconds", "inter message timestamps (as sent by remote)", {90e-3, 110e-3, 1e-3, }},
{ "gap_received", "seconds", "Histogram for inter message arrival time (as seen by this instance)", {90e-3, 110e-3, 1e-3, }},
{ "owd", "seconds", "Histogram for one-way-delay (OWD) of received messages", {0, 1, 100e-3, }}
{ "skipped", "samples", "skipped samples by hooks", 25 },
{ "reorderd", "samples", "reordered samples", 25 },
{ "gap_sample", "seconds", "inter message timestamps (as sent by remote)", 25 },
{ "gap_received", "seconds", "Histogram for inter message arrival time (as seen by this instance)", 25 },
{ "owd", "seconds", "Histogram for one-way-delay (OWD) of received messages", 25 }
};
int stats_init(struct stats *s)
int stats_init(struct stats *s, int buckets, int warmup)
{
for (int i = 0; i < STATS_COUNT; i++) {
struct stats_desc *desc = &stats_table[i];
hist_init(&s->histograms[i], desc->hist.min, desc->hist.max, desc->hist.resolution);
}
for (int i = 0; i < STATS_COUNT; i++)
hist_init(&s->histograms[i], buckets, warmup);
s->delta = alloc(sizeof(struct stats_delta));
@ -245,4 +238,4 @@ enum stats_id stats_lookup_id(const char *name)
}
return -1;
}
}

View file

@ -43,6 +43,9 @@ static struct node *node;
static int running = 1; /**< Initiate shutdown if zero */
static int count = -1; /**< Amount of messages which should be sent (default: -1 for unlimited) */
static hist_cnt_t hist_warmup;
static int hist_buckets;
/** File descriptor for Matlab results.
* This allows you to write Matlab results in a seperate log file:
*
@ -50,11 +53,6 @@ static int count = -1; /**< Amount of messages which should be sent (default:
*/
static int fd = STDOUT_FILENO;
/* Histogram */
static double low = 0; /**< Lowest value in histogram. */
static double high = 2e-4; /**< Highest value in histogram. */
static double res = 1e-5; /**< Histogram resolution. */
#define CLOCK_ID CLOCK_MONOTONIC
/* Prototypes */
@ -73,9 +71,8 @@ void usage()
printf(" OPTIONS is one or more of the following options:\n");
printf(" -c CNT send CNT messages\n");
printf(" -f FD use file descriptor FD for result output instead of stdout\n");
printf(" -l LOW smallest value for histogram\n");
printf(" -H HIGH largest value for histogram\n");
printf(" -r RES bucket resolution for histogram\n");
printf(" -b BKTS number of buckets for histogram\n");
printf(" -w WMUP duration of histogram warmup phase\n");
printf(" -h show this usage information\n");
printf("\n");
@ -86,7 +83,7 @@ int main(int argc, char *argv[])
{
/* Parse Arguments */
char c, *endptr;
while ((c = getopt (argc, argv, "l:hH:r:f:c:")) != -1) {
while ((c = getopt (argc, argv, "w:h:r:f:c:b:")) != -1) {
switch (c) {
case 'c':
count = strtoul(optarg, &endptr, 10);
@ -94,14 +91,11 @@ int main(int argc, char *argv[])
case 'f':
fd = strtoul(optarg, &endptr, 10);
goto check;
case 'l':
low = strtod(optarg, &endptr);
case 'w':
hist_warmup = strtoul(optarg, &endptr, 10);
goto check;
case 'H':
high = strtod(optarg, &endptr);
goto check;
case 'r':
res = strtod(optarg, &endptr);
case 'b':
hist_buckets = strtoul(optarg, &endptr, 10);
goto check;
case 'h':
case '?':
@ -157,7 +151,7 @@ void test_rtt() {
struct sample *smp_send = alloc(SAMPLE_LEN(2));
struct sample *smp_recv = alloc(SAMPLE_LEN(2));
hist_init(&hist, low, high, res);
hist_init(&hist, 20, 100);
/* Print header */
fprintf(stdout, "%17s%5s%10s%10s%10s%10s%10s\n", "timestamp", "seq", "rtt", "min", "max", "mean", "stddev");