diff options
| author | Will Hawkins <[email protected]> | 2022-11-07 18:29:03 -0500 |
|---|---|---|
| committer | Will Hawkins <[email protected]> | 2022-11-07 18:32:01 -0500 |
| commit | 86f822c37f8fcc70d3a1085f4769ec58752f50c1 (patch) | |
| tree | 5f1a1e070590d5669b0c36eab1faaba99e4478af | |
| parent | 715e074b068d98bdf466ed33e08a1f54b31c3d44 (diff) | |
[Feature] Redefine stability
Stability (in rev3) is based on whether the standard deviations of the
measurements are within a certain percentage of the average. This commit
adds that functionality.
| -rw-r--r-- | constants/constants.go | 26 | ||||
| -rw-r--r-- | stabilizer/rev3.go | 50 |
2 files changed, 56 insertions, 20 deletions
diff --git a/constants/constants.go b/constants/constants.go index c4f2c20..6934459 100644 --- a/constants/constants.go +++ b/constants/constants.go @@ -17,17 +17,21 @@ package constants import "time" var ( - // The initial number of connections on a LBC. - StartingNumberOfLoadGeneratingConnections uint64 = 4 - // The number of intervals for which to account in a moving-average - // calculation. - MovingAverageIntervalCount int = 4 - // The number of intervals across which to consider a moving average stable. - MovingAverageStabilitySpan uint64 = 4 - // The number of connections to add to a LBC when unsaturated. - AdditiveNumberOfLoadGeneratingConnections uint64 = 4 - // The cutoff of the percent difference that defines instability. - InstabilityDelta float64 = 5 + // The initial number of load-generating connections when attempting to saturate the network. + StartingNumberOfLoadGeneratingConnections uint64 = 1 + // The number of load-generating connections to add at each interval while attempting to + // saturate the network. + AdditiveNumberOfLoadGeneratingConnections uint64 = 1 + + // The number of previous instantaneous measurements to consider when generating the so-called + // instantaneous moving averages of a measurement. + InstantaneousThroughputMeasurementCount int = 4 + InstantaneousProbeMeasurementCount int = 1 + // The number of instantaneous moving averages to consider when determining stability. + InstantaneousMovingAverageCount int = 4 + // The standard deviation cutoff used to determine stability among the K preceding moving averages + // of a measurement (as a percentage of the mean). + StabilityStandardDeviation float64 = 5.0 // The amount of time that the client will cooldown if it is in debug mode. CooldownPeriod time.Duration = 4 * time.Second diff --git a/stabilizer/rev3.go b/stabilizer/rev3.go index e81fc76..2e29626 100644 --- a/stabilizer/rev3.go +++ b/stabilizer/rev3.go @@ -40,8 +40,14 @@ func NewProbeStabilizer(i int, k int, s float64, debugLevel debug.DebugLevel, de func (r3 *ProbeStabilizer) AddMeasurement(measurement rpm.ProbeDataPoint) { r3.m.Lock() defer r3.m.Unlock() - // Add this instantaneous measurement to the mix of the I previous instantaneous measurements. - r3.instantaneousMeasurements.AddElement(measurement.Duration.Seconds()) + + // There may be more than one round trip accumulated together. If that is the case, + // we will blow them apart in to three separate measurements and each one will just + // be 1 / measurement.RoundTripCount of the total length. + for range utilities.Iota(0, int(measurement.RoundTripCount)) { + // Add this instantaneous measurement to the mix of the I previous instantaneous measurements. + r3.instantaneousMeasurements.AddElement(measurement.Duration.Seconds() / float64(measurement.RoundTripCount)) + } // Calculate the moving average of the I previous instantaneous measurements and add it to // the mix of K previous moving averages. r3.movingAverages.AddElement(r3.instantaneousMeasurements.CalculateAverage()) @@ -58,14 +64,27 @@ func (r3 *ProbeStabilizer) AddMeasurement(measurement rpm.ProbeDataPoint) { func (r3 *ProbeStabilizer) IsStable() bool { // calculate whether the standard deviation of the K previous moving averages falls below S. - islt, stddev := r3.movingAverages.StandardDeviationLessThan(r3.stabilityStandardDeviation) + isvalid, stddev := r3.movingAverages.StandardDeviation() + + if !isvalid { + // If there are not enough values in the series to be able to calculate a + // standard deviation, then we know that we are not yet stable. Vamoose. + return false + } + + // Stability is determined by whether or not the standard deviation of the values + // is within 5% of the average. + stabilityCutoff := r3.movingAverages.CalculateAverage() * (r3.stabilityStandardDeviation / 100.0) + isStable := stddev <= stabilityCutoff if debug.IsDebug(r3.dbgLevel) { fmt.Printf( - "%s: Standard Deviation: %f s; Is Normally Distributed? %v).\n", + "%s: Is Stable? %v; Standard Deviation: %f s; Is Normally Distributed? %v; Standard Deviation Cutoff: %v s).\n", r3.dbgConfig.String(), + isStable, stddev, r3.movingAverages.IsNormallyDistributed(), + stabilityCutoff, ) fmt.Printf("%s: Values: ", r3.dbgConfig.String()) for _, v := range r3.movingAverages.Values() { @@ -73,7 +92,8 @@ func (r3 *ProbeStabilizer) IsStable() bool { } fmt.Printf("\n") } - return islt + + return isStable } func NewThroughputStabilizer(i int, k int, s float64, debugLevel debug.DebugLevel, debug *debug.DebugWithPrefix) ThroughputStabilizer { @@ -104,15 +124,27 @@ func (r3 *ThroughputStabilizer) AddMeasurement(measurement rpm.ThroughputDataPoi } func (r3 *ThroughputStabilizer) IsStable() bool { - // calculate whether the standard deviation of the K previous moving averages falls below S. - islt, stddev := r3.movingAverages.StandardDeviationLessThan(r3.stabilityStandardDeviation) + isvalid, stddev := r3.movingAverages.StandardDeviation() + + if !isvalid { + // If there are not enough values in the series to be able to calculate a + // standard deviation, then we know that we are not yet stable. Vamoose. + return false + } + + // Stability is determined by whether or not the standard deviation of the values + // is within 5% of the average. + stabilityCutoff := r3.movingAverages.CalculateAverage() * (r3.stabilityStandardDeviation / 100.0) + isStable := stddev <= stabilityCutoff if debug.IsDebug(r3.dbgLevel) { fmt.Printf( - "%s: Standard Deviation: %f Mbps; Is Normally Distributed? %v).\n", + "%s: Is Stable? %v; Standard Deviation: %f Mbps; Is Normally Distributed? %v; Standard Deviation Cutoff: %v Mbps).\n", r3.dbgConfig.String(), + isStable, stddev, r3.movingAverages.IsNormallyDistributed(), + stabilityCutoff, ) fmt.Printf("%s: Values: ", r3.dbgConfig.String()) for _, v := range r3.movingAverages.Values() { @@ -120,5 +152,5 @@ func (r3 *ThroughputStabilizer) IsStable() bool { } fmt.Printf("\n") } - return islt + return isStable } |
