Merge pull request #189 from HyNetwork/wip-cc-optimizations

CC optimizations
This commit is contained in:
Toby 2022-01-03 22:23:28 -08:00 committed by GitHub
commit 55d8ccf61e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -6,9 +6,9 @@ import (
) )
const ( const (
ackRateMinSampleInterval = 4 * time.Second pktInfoSlotCount = 4
ackRateMaxSampleInterval = 20 * time.Second minSampleCount = 50
ackRateMinACKSampleCount = 100 minAckRate = 0.75
) )
type BrutalSender struct { type BrutalSender struct {
@ -17,10 +17,13 @@ type BrutalSender struct {
maxDatagramSize congestion.ByteCount maxDatagramSize congestion.ByteCount
pacer *pacer pacer *pacer
ackCount, lossCount uint64 pktInfoSlots [pktInfoSlotCount]pktInfo
ackRate float64 }
ackRateNextUpdateMin time.Time
ackRateNextUpdateMax time.Time type pktInfo struct {
Timestamp int64
AckCount uint64
LossCount uint64
} }
func NewBrutalSender(bps congestion.ByteCount) *BrutalSender { func NewBrutalSender(bps congestion.ByteCount) *BrutalSender {
@ -64,14 +67,30 @@ func (b *BrutalSender) OnPacketSent(sentTime time.Time, bytesInFlight congestion
func (b *BrutalSender) OnPacketAcked(number congestion.PacketNumber, ackedBytes congestion.ByteCount, func (b *BrutalSender) OnPacketAcked(number congestion.PacketNumber, ackedBytes congestion.ByteCount,
priorInFlight congestion.ByteCount, eventTime time.Time) { priorInFlight congestion.ByteCount, eventTime time.Time) {
b.ackCount += 1 currentTimestamp := eventTime.Unix()
b.maybeUpdateACKRate() slot := currentTimestamp % pktInfoSlotCount
if b.pktInfoSlots[slot].Timestamp == currentTimestamp {
b.pktInfoSlots[slot].AckCount++
} else {
// uninitialized slot or too old, reset
b.pktInfoSlots[slot].Timestamp = currentTimestamp
b.pktInfoSlots[slot].AckCount = 1
b.pktInfoSlots[slot].LossCount = 0
}
} }
func (b *BrutalSender) OnPacketLost(number congestion.PacketNumber, lostBytes congestion.ByteCount, func (b *BrutalSender) OnPacketLost(number congestion.PacketNumber, lostBytes congestion.ByteCount,
priorInFlight congestion.ByteCount) { priorInFlight congestion.ByteCount) {
b.lossCount += 1 currentTimestamp := time.Now().Unix()
b.maybeUpdateACKRate() slot := currentTimestamp % pktInfoSlotCount
if b.pktInfoSlots[slot].Timestamp == currentTimestamp {
b.pktInfoSlots[slot].LossCount++
} else {
// uninitialized slot or too old, reset
b.pktInfoSlots[slot].Timestamp = currentTimestamp
b.pktInfoSlots[slot].AckCount = 0
b.pktInfoSlots[slot].LossCount = 1
}
} }
func (b *BrutalSender) SetMaxDatagramSize(size congestion.ByteCount) { func (b *BrutalSender) SetMaxDatagramSize(size congestion.ByteCount) {
@ -79,36 +98,26 @@ func (b *BrutalSender) SetMaxDatagramSize(size congestion.ByteCount) {
b.pacer.SetMaxDatagramSize(size) b.pacer.SetMaxDatagramSize(size)
} }
func (b *BrutalSender) maybeUpdateACKRate() { func (b *BrutalSender) getAckRate() float64 {
now := time.Now() now := time.Now()
if !now.After(b.ackRateNextUpdateMin) { currentTimestamp := now.Unix()
return minTimestamp := currentTimestamp - pktInfoSlotCount
} var ackCount, lossCount uint64
// Min interval reached for _, info := range b.pktInfoSlots {
if b.ackCount >= ackRateMinACKSampleCount { if info.Timestamp < minTimestamp {
// And enough samples, update ackRate now continue
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)
} }
ackCount += info.AckCount
lossCount += info.LossCount
} }
} if ackCount+lossCount < minSampleCount {
return 1
func (b *BrutalSender) getAckRate() (rate float64) {
rate = b.ackRate
if rate <= 0 {
rate = 1
} else if rate < 0.5 {
rate = 0.5
} }
return rate := float64(ackCount) / float64(ackCount+lossCount)
if rate < minAckRate {
return minAckRate
}
return rate
} }
func (b *BrutalSender) InSlowStart() bool { func (b *BrutalSender) InSlowStart() bool {