From 246c2ce89c556bf47cb5e17ecd81d9e109246e99 Mon Sep 17 00:00:00 2001 From: Toby Date: Fri, 10 Apr 2020 13:57:28 -0700 Subject: [PATCH] Throughput optimizations --- go.mod | 2 +- go.sum | 4 ++-- pkg/congestion/brutal.go | 44 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index ca0d4ef..da9de56 100644 --- a/go.mod +++ b/go.mod @@ -6,4 +6,4 @@ require github.com/golang/protobuf v1.3.1 require github.com/lucas-clemente/quic-go v0.15.2 -replace github.com/lucas-clemente/quic-go => github.com/tobyxdd/quic-go v0.1.1-tquic-1 +replace github.com/lucas-clemente/quic-go => github.com/tobyxdd/quic-go v0.1.2-tquic-1 diff --git a/go.sum b/go.sum index 9a5c0c4..69ed689 100644 --- a/go.sum +++ b/go.sum @@ -115,8 +115,8 @@ github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= -github.com/tobyxdd/quic-go v0.1.1-tquic-1 h1:KDhDFNe+IlI+ZOvEG6wA5JcNq8OUO029OYi8bq7XnSU= -github.com/tobyxdd/quic-go v0.1.1-tquic-1/go.mod h1:qxmO5Y4ZMhdNkunGfxuZnZXnJwYpW9vjQkyrZ7BsgUI= +github.com/tobyxdd/quic-go v0.1.2-tquic-1 h1:PPbkQyNNlI2ZXFWDspBGvOTXAWTX/y82mVy+kDzKtgY= +github.com/tobyxdd/quic-go v0.1.2-tquic-1/go.mod h1:qxmO5Y4ZMhdNkunGfxuZnZXnJwYpW9vjQkyrZ7BsgUI= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= diff --git a/pkg/congestion/brutal.go b/pkg/congestion/brutal.go index ae22e35..491bdd8 100644 --- a/pkg/congestion/brutal.go +++ b/pkg/congestion/brutal.go @@ -5,11 +5,22 @@ import ( "time" ) +const ( + ackRateMinSampleInterval = 4 * time.Second + ackRateMaxSampleInterval = 20 * time.Second + ackRateMinACKSampleCount = 200 +) + // BrutalSender sends packets at a constant rate and does not react to any changes in the network environment, // hence the name. type BrutalSender struct { rttStats *congestion.RTTStats bps congestion.ByteCount + + ackCount, lossCount uint64 + ackRate float64 + ackRateNextUpdateMin time.Time + ackRateNextUpdateMax time.Time } func NewBrutalSender(bps congestion.ByteCount) *BrutalSender { @@ -27,7 +38,13 @@ func (b *BrutalSender) TimeUntilSend(bytesInFlight congestion.ByteCount) time.Du } func (b *BrutalSender) CanSend(bytesInFlight congestion.ByteCount) bool { - return bytesInFlight < b.GetCongestionWindow() + if b.ackRate == 0 { + return bytesInFlight < b.GetCongestionWindow() + } else if b.ackRate > 0.5 { + return bytesInFlight < congestion.ByteCount(float64(b.GetCongestionWindow())/b.ackRate) + } else { + return bytesInFlight < b.GetCongestionWindow()*2 + } } func (b *BrutalSender) GetCongestionWindow() congestion.ByteCount { @@ -44,10 +61,35 @@ func (b *BrutalSender) OnPacketSent(sentTime time.Time, bytesInFlight congestion func (b *BrutalSender) OnPacketAcked(number congestion.PacketNumber, ackedBytes congestion.ByteCount, priorInFlight congestion.ByteCount, eventTime time.Time) { + b.ackCount += 1 + b.maybeUpdateACKRate() } func (b *BrutalSender) OnPacketLost(number congestion.PacketNumber, lostBytes congestion.ByteCount, priorInFlight congestion.ByteCount) { + b.lossCount += 1 + b.maybeUpdateACKRate() +} + +func (b *BrutalSender) maybeUpdateACKRate() { + now := time.Now() + if !now.After(b.ackRateNextUpdateMin) { + return + } + // Min interval reached + if b.ackCount >= ackRateMinACKSampleCount { + b.ackRate = float64(b.ackCount) / float64(b.ackCount+b.lossCount) + b.ackCount, b.lossCount = 0, 0 + b.ackRateNextUpdateMin = now.Add(ackRateMinSampleInterval) + b.ackRateNextUpdateMax = now.Add(ackRateMaxSampleInterval) + } else { + if now.After(b.ackRateNextUpdateMax) { + // Max interval reached, still not enough samples, reset + b.ackCount, b.lossCount = 0, 0 + b.ackRateNextUpdateMin = now.Add(ackRateMinSampleInterval) + b.ackRateNextUpdateMax = now.Add(ackRateMaxSampleInterval) + } + } } func (b *BrutalSender) InSlowStart() bool {