diff options
author | jonmv <venstad@gmail.com> | 2024-05-13 12:21:20 +0200 |
---|---|---|
committer | jonmv <venstad@gmail.com> | 2024-05-13 12:21:20 +0200 |
commit | c6d8d30bd76f426cd8b2fd45c125c6da57c768f1 (patch) | |
tree | 3fa36fd75cf812ef9291ea821bb5ae72d3add106 /client/go/internal | |
parent | f951681e3e1076606da092437a32c92454533e14 (diff) |
Improve feed throttler and tests
Diffstat (limited to 'client/go/internal')
-rw-r--r-- | client/go/internal/vespa/document/throttler.go | 25 | ||||
-rw-r--r-- | client/go/internal/vespa/document/throttler_test.go | 7 |
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 { |