提交 ffed2ce6 编写于 作者: M mikael

7158457: division by zero in adaptiveweightedaverage

Summary: Add ceiling to AdaptiveWeightedAverage
Reviewed-by: ysr, iveresov
上级 d524aa32
...@@ -31,9 +31,15 @@ float AdaptiveWeightedAverage::compute_adaptive_average(float new_sample, ...@@ -31,9 +31,15 @@ float AdaptiveWeightedAverage::compute_adaptive_average(float new_sample,
float average) { float average) {
// We smooth the samples by not using weight() directly until we've // We smooth the samples by not using weight() directly until we've
// had enough data to make it meaningful. We'd like the first weight // had enough data to make it meaningful. We'd like the first weight
// used to be 1, the second to be 1/2, etc until we have 100/weight // used to be 1, the second to be 1/2, etc until we have
// samples. // OLD_THRESHOLD/weight samples.
unsigned count_weight = 100/count(); unsigned count_weight = 0;
// Avoid division by zero if the counter wraps (7158457)
if (!is_old()) {
count_weight = OLD_THRESHOLD/count();
}
unsigned adaptive_weight = (MAX2(weight(), count_weight)); unsigned adaptive_weight = (MAX2(weight(), count_weight));
float new_avg = exp_avg(average, new_sample, adaptive_weight); float new_avg = exp_avg(average, new_sample, adaptive_weight);
...@@ -43,8 +49,6 @@ float AdaptiveWeightedAverage::compute_adaptive_average(float new_sample, ...@@ -43,8 +49,6 @@ float AdaptiveWeightedAverage::compute_adaptive_average(float new_sample,
void AdaptiveWeightedAverage::sample(float new_sample) { void AdaptiveWeightedAverage::sample(float new_sample) {
increment_count(); increment_count();
assert(count() != 0,
"Wraparound -- history would be incorrectly discarded");
// Compute the new weighted average // Compute the new weighted average
float new_avg = compute_adaptive_average(new_sample, average()); float new_avg = compute_adaptive_average(new_sample, average());
......
...@@ -50,11 +50,20 @@ class AdaptiveWeightedAverage : public CHeapObj { ...@@ -50,11 +50,20 @@ class AdaptiveWeightedAverage : public CHeapObj {
unsigned _weight; // The weight used to smooth the averages unsigned _weight; // The weight used to smooth the averages
// A higher weight favors the most // A higher weight favors the most
// recent data. // recent data.
bool _is_old; // Has enough historical data
const static unsigned OLD_THRESHOLD = 100;
protected: protected:
float _last_sample; // The last value sampled. float _last_sample; // The last value sampled.
void increment_count() { _sample_count++; } void increment_count() {
_sample_count++;
if (!_is_old && _sample_count > OLD_THRESHOLD) {
_is_old = true;
}
}
void set_average(float avg) { _average = avg; } void set_average(float avg) { _average = avg; }
// Helper function, computes an adaptive weighted average // Helper function, computes an adaptive weighted average
...@@ -64,13 +73,15 @@ class AdaptiveWeightedAverage : public CHeapObj { ...@@ -64,13 +73,15 @@ class AdaptiveWeightedAverage : public CHeapObj {
public: public:
// Input weight must be between 0 and 100 // Input weight must be between 0 and 100
AdaptiveWeightedAverage(unsigned weight, float avg = 0.0) : AdaptiveWeightedAverage(unsigned weight, float avg = 0.0) :
_average(avg), _sample_count(0), _weight(weight), _last_sample(0.0) { _average(avg), _sample_count(0), _weight(weight), _last_sample(0.0),
_is_old(false) {
} }
void clear() { void clear() {
_average = 0; _average = 0;
_sample_count = 0; _sample_count = 0;
_last_sample = 0; _last_sample = 0;
_is_old = false;
} }
// Useful for modifying static structures after startup. // Useful for modifying static structures after startup.
...@@ -84,7 +95,8 @@ class AdaptiveWeightedAverage : public CHeapObj { ...@@ -84,7 +95,8 @@ class AdaptiveWeightedAverage : public CHeapObj {
float average() const { return _average; } float average() const { return _average; }
unsigned weight() const { return _weight; } unsigned weight() const { return _weight; }
unsigned count() const { return _sample_count; } unsigned count() const { return _sample_count; }
float last_sample() const { return _last_sample; } float last_sample() const { return _last_sample; }
bool is_old() const { return _is_old; }
// Update data with a new sample. // Update data with a new sample.
void sample(float new_sample); void sample(float new_sample);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册