mirror of https://github.com/BOINC/boinc.git
58 lines
1.4 KiB
C
58 lines
1.4 KiB
C
// structure for tracking the recent mean
|
|
// of a distribution that may change over time
|
|
//
|
|
|
|
#include <math.h>
|
|
|
|
#define MIN_SAMPLES 50000
|
|
// after this many samples, use exponential average
|
|
#define SAMPLE_WEIGHT 0.005
|
|
// new samples get this weight in exp avg
|
|
#define SAMPLE_LIMIT 20
|
|
// cap samples at recent_mean*limit
|
|
|
|
struct AVERAGE {
|
|
double n; // double to avoid integer overflow
|
|
double sum;
|
|
double exp_avg;
|
|
|
|
void update(double sample) {
|
|
double delta, limit;
|
|
if (sample < 0) return;
|
|
if (n > MIN_SAMPLES) {
|
|
if (sample > exp_avg*SAMPLE_LIMIT) {
|
|
printf(" truncating sample: %.0fG exp_avg %.0fG\n",
|
|
sample/1e9, exp_avg/1e9
|
|
);
|
|
sample = exp_avg*SAMPLE_LIMIT;
|
|
}
|
|
} else {
|
|
double x = sum/n;
|
|
if (sample > x*SAMPLE_LIMIT) {
|
|
printf(" truncating sample: %.0fG avg %.0fG\n",
|
|
sample/1e9, x/1e9
|
|
);
|
|
sample = x*SAMPLE_LIMIT;
|
|
}
|
|
}
|
|
n++;
|
|
|
|
sum += sample;
|
|
if (n < MIN_SAMPLES) {
|
|
exp_avg = sum/n;
|
|
} else {
|
|
delta = sample - exp_avg;
|
|
exp_avg += SAMPLE_WEIGHT*delta;
|
|
}
|
|
}
|
|
inline double get_mean() {
|
|
return exp_avg;
|
|
}
|
|
|
|
void clear() {
|
|
n = 0;
|
|
sum = 0;
|
|
exp_avg = 0;
|
|
}
|
|
};
|