]> rtime.felk.cvut.cz Git - can-benchmark.git/blobdiff - latester/histogram.h
latester: Add statistics about data out of histogram range
[can-benchmark.git] / latester / histogram.h
index ad7591ccccf7f1220f80d3488307ff6560da0cd5..52dc66427c1b6fe1e52544e1476e79ad6c0f89af 100644 (file)
@@ -3,6 +3,7 @@
 
 struct histogram {
        unsigned *data;
+       unsigned out_below, out_above;
        unsigned allocated;
        unsigned resolution;
 };
@@ -14,6 +15,7 @@ int histogram_init(struct histogram *h,
        size_t mem;
        h->allocated = max_value/resolution + 1;
        h->resolution = resolution;
+       h->out_below = h->out_above = 0;
        mem = h->allocated*sizeof(*h->data);
        h->data = malloc(mem);
        if (h->data) {
@@ -23,11 +25,17 @@ int histogram_init(struct histogram *h,
                return -1;
 }
 
-void histogram_add(struct histogram *h, unsigned value)
+void histogram_add(struct histogram *h, int value)
 {
+       if (value < 0) {
+               h->out_below++;
+               return;
+       }
        unsigned index = value / h->resolution;
-       if (index >= h->allocated)
+       if (index >= h->allocated) {
+               h->out_above++;
                index = h->allocated - 1;
+       }
        h->data[index]++;
 }
 
@@ -35,20 +43,61 @@ void histogram_fprint(struct histogram *h, FILE *f)
 {
        unsigned long long sum = 0, cum;
        unsigned i;
+
+       if (!f)
+               return;
+
        for (i = 0; i < h->allocated; i++)
                sum += h->data[i];
        cum = sum;
        for (i = 0; i < h->allocated; i++) {
                if (h->data[i] != 0) {
-                       if (!getenv("CANPING_MS"))
-                               fprintf(f, "%d %lld\n", i*h->resolution, cum);
-                       else
-                               fprintf(f, "%g %lld\n", 1e-3*(i*h->resolution), cum);
+                       fprintf(f, "%g %lld\n", 1e-3*(i*h->resolution), cum);
                }
                cum -= h->data[i];
        }
 }
 
 
+struct histogram_stats {
+       unsigned count;
+       unsigned long long sum;
+       unsigned avg;
+       unsigned below, above;  /* Count of data out of histogram range */
+       unsigned percentile[101];
+};
+
+void histogram_stats(struct histogram *h, struct histogram_stats *s)
+{
+       unsigned long long sum;
+       unsigned i, j;
+
+       if (!s)
+               return;
+
+       memset(s, 0, sizeof(*s));
+
+       for (i = 0; i < h->allocated; i++) {
+               s->count += h->data[i];
+               s->sum += h->data[i] * i * h->resolution;
+       }
+       if (s->count == 0)
+               return;
+
+       s->avg = s->sum / s->count;
+
+       for (i = 0, j = 0, sum = 0; i < 100; i++) {
+               while (sum <= i * s->count / 100)
+                       sum += h->data[j++];
+
+               s->percentile[i] = (j-1) * h->resolution;
+       }
+       while (sum < i * s->count / 100)
+               sum += h->data[j++];
+       s->percentile[100] = (j-1) * h->resolution;
+
+       s->below = h->out_below;
+       s->above = h->out_above;
+}
 
 #endif