Document roughness. Remove an unexplained factor of 2 and handle window edges better. Subtract 1 from roughness to correspond better to variance.

This commit is contained in:
A.J. Beamon 2020-02-25 08:45:51 -08:00
parent 083e3f38f3
commit 0f7656e52e
2 changed files with 32 additions and 7 deletions

View File

@ -22,7 +22,7 @@
#include "flow/actorcompiler.h" // has to be last include
Counter::Counter(std::string const& name, CounterCollection& collection)
: name(name), interval_start(0), last_event(0), interval_sq_time(0), interval_start_value(0), interval_delta(0)
: name(name), interval_start(0), last_event(0), interval_sq_time(0), interval_start_value(0), interval_delta(0), roughness_interval_start(0)
{
metric.init(collection.name + "." + (char)toupper(name.at(0)) + name.substr(1), collection.id);
collection.counters.push_back(this);
@ -45,13 +45,21 @@ double Counter::getRate() const {
}
double Counter::getRoughness() const {
double elapsed = now() - interval_start;
double elapsed = now() - roughness_interval_start;
if(elapsed == 0) {
return 0;
}
// If we have time samples t in T, and let:
// n = size(T) = interval_delta
// m = mean(T) = elapsed / interval_delta
// v = sum(t^2) for t in T = interval_sq_time
//
// The formula below is: (v/(m*n)) / m - 1
// This is equivalent to (v/n - m^2) / m^2 = Variance(T)/m^2
// Variance(T)/m^2 is equal to Variance(t/m) for t in T
double delay = interval_sq_time / elapsed;
return delay * getRate() * 2;
return delay * interval_delta / elapsed - 1;
}
void Counter::resetInterval() {
@ -59,7 +67,10 @@ void Counter::resetInterval() {
interval_delta = 0;
interval_sq_time = 0;
interval_start = now();
last_event = interval_start; // <FIXME: Is this right?
if(last_event == 0) {
last_event = interval_start;
}
roughness_interval_start = last_event;
}
void Counter::clear() {

View File

@ -91,14 +91,28 @@ public:
Value getIntervalDelta() const { return interval_delta; }
Value getValue() const { return interval_start_value + interval_delta; }
double getRate() const; // dValue / dt
double getRoughness() const; // value deltas come in "clumps" of this many ( 1 = periodic, 2 = poisson, 10 = periodic clumps of 10 (nearly) simultaneous delta )
// dValue / dt
double getRate() const;
// Measures the clumpiness or dispersion of the counter.
// Computed as a normalized variance of the time between each incrementation of the value.
// A delta of N is treated as N distinct increments, with N-1 increments having time span 0.
// Normalization is performed by dividing each time sample by the mean time before taking variance.
//
// roughness = Variance(t/mean(T)) for time samples t in T
//
// A uniformly periodic counter will have roughness of 0
// A uniformly periodic counter that increases in clumps of N will have roughness of N-1
// A poisson distributed counter will have roughness of 1
double getRoughness() const;
bool hasRate() const { return true; }
bool hasRoughness() const { return true; }
private:
std::string name;
double interval_start, last_event, interval_sq_time;
double interval_start, last_event, interval_sq_time, roughness_interval_start;
Value interval_delta, interval_start_value;
Int64MetricHandle metric;
};