aboutsummaryrefslogtreecommitdiffstats
path: root/client/go/internal
diff options
context:
space:
mode:
authorjonmv <venstad@gmail.com>2024-05-13 12:21:20 +0200
committerjonmv <venstad@gmail.com>2024-05-13 12:21:20 +0200
commitc6d8d30bd76f426cd8b2fd45c125c6da57c768f1 (patch)
tree3fa36fd75cf812ef9291ea821bb5ae72d3add106 /client/go/internal
parentf951681e3e1076606da092437a32c92454533e14 (diff)
Improve feed throttler and tests
Diffstat (limited to 'client/go/internal')
-rw-r--r--client/go/internal/vespa/document/throttler.go25
-rw-r--r--client/go/internal/vespa/document/throttler_test.go7
2 files changed, 28 insertions, 4 deletions
diff --git a/client/go/internal/vespa/document/throttler.go b/client/go/internal/vespa/document/throttler.go
index 0400ba1a150..3eb0ccd17f6 100644
--- a/client/go/internal/vespa/document/throttler.go
+++ b/client/go/internal/vespa/document/throttler.go
@@ -73,8 +73,12 @@ func (t *dynamicThrottler) Sent() {
t.throughputs[index] = currentThroughput
// Loop over throughput measurements and pick the one which optimises throughput and latency.
- choice := float64(currentInflight)
+ best := float64(currentInflight)
maxObjective := float64(-1)
+ choice := 0
+ j := -1
+ k := -1
+ s := 0.0
for i := len(t.throughputs) - 1; i >= 0; i-- {
if t.throughputs[i] == 0 {
continue // Skip unknown values
@@ -83,10 +87,25 @@ func (t *dynamicThrottler) Sent() {
objective := t.throughputs[i] * math.Pow(inflight, throttlerWeight-1) // Optimise throughput (weight), but also latency (1 - weight)
if objective > maxObjective {
maxObjective = objective
- choice = inflight
+ best = inflight
+ choice = i
}
+ // Additionally, smooth the throughput values, to reduce the impact of noise, and reduce jumpiness
+ if j != -1 {
+ u := t.throughputs[j]
+ if k != -1 {
+ t.throughputs[j] = (2*u + t.throughputs[i] + s) / 4
+ }
+ s = u
+ }
+ k = j
+ j = i
+ }
+ target := int64((rand.Float64()*0.40+0.84)*best + rand.Float64()*4 - 1) // Random walk, skewed towards increase
+ // If the best inflight is at the high end of the known, we override the random walk to speed up upwards exploration
+ if choice == j && choice+1 < len(t.throughputs) {
+ target = int64(1 + float64(t.minInflight)*math.Pow(256, (float64(choice)+1.5)/float64(len(t.throughputs))))
}
- target := int64((rand.Float64()*0.20 + 0.92) * choice) // Random walk, skewed towards increase
t.targetInflight.Store(max(t.minInflight, min(t.maxInflight, target)))
}
diff --git a/client/go/internal/vespa/document/throttler_test.go b/client/go/internal/vespa/document/throttler_test.go
index 410e518e596..b386e0d5105 100644
--- a/client/go/internal/vespa/document/throttler_test.go
+++ b/client/go/internal/vespa/document/throttler_test.go
@@ -9,11 +9,16 @@ import (
func TestThrottler(t *testing.T) {
clock := &manualClock{tick: time.Second}
tr := newThrottler(8, clock.now)
+
if got, want := tr.TargetInflight(), int64(16); got != want {
t.Errorf("got TargetInflight() = %d, but want %d", got, want)
}
- for tr.TargetInflight() < int64(18) {
+ for i := 0; i < 30; i++ {
tr.Sent()
+ tr.Success()
+ }
+ if got, want := tr.TargetInflight(), int64(18); got != want {
+ t.Errorf("got TargetInflight() = %d, but want %d", got, want)
}
tr.Throttled(34)
if got, want := tr.TargetInflight(), int64(17); got != want {