Source File
hybrid_slow_start.go
Belonging Package
github.com/quic-go/quic-go/internal/congestion
package congestionimport ()// Note(pwestin): the magic clamping numbers come from the original code in// tcp_cubic.c.const hybridStartLowWindow = protocol.ByteCount(16)// Number of delay samples for detecting the increase of delay.const hybridStartMinSamples = uint32(8)// Exit slow start if the min rtt has increased by more than 1/8th.const hybridStartDelayFactorExp = 3 // 2^3 = 8// The original paper specifies 2 and 8ms, but those have changed over time.const (hybridStartDelayMinThresholdUs = int64(4000)hybridStartDelayMaxThresholdUs = int64(16000))// HybridSlowStart implements the TCP hybrid slow start algorithmtype HybridSlowStart struct {endPacketNumber protocol.PacketNumberlastSentPacketNumber protocol.PacketNumberstarted boolcurrentMinRTT time.DurationrttSampleCount uint32hystartFound bool}// StartReceiveRound is called for the start of each receive round (burst) in the slow start phase.func ( *HybridSlowStart) ( protocol.PacketNumber) {.endPacketNumber =.currentMinRTT = 0.rttSampleCount = 0.started = true}// IsEndOfRound returns true if this ack is the last packet number of our current slow start round.func ( *HybridSlowStart) ( protocol.PacketNumber) bool {return .endPacketNumber <}// ShouldExitSlowStart should be called on every new ack frame, since a new// RTT measurement can be made then.// rtt: the RTT for this ack packet.// minRTT: is the lowest delay (RTT) we have seen during the session.// congestionWindow: the congestion window in packets.func ( *HybridSlowStart) ( time.Duration, time.Duration, protocol.ByteCount) bool {if !.started {// Time to start the hybrid slow start..StartReceiveRound(.lastSentPacketNumber)}if .hystartFound {return true}// Second detection parameter - delay increase detection.// Compare the minimum delay (s.currentMinRTT) of the current// burst of packets relative to the minimum delay during the session.// Note: we only look at the first few(8) packets in each burst, since we// only want to compare the lowest RTT of the burst relative to previous// bursts..rttSampleCount++if .rttSampleCount <= hybridStartMinSamples {if .currentMinRTT == 0 || .currentMinRTT > {.currentMinRTT =}}// We only need to check this once per round.if .rttSampleCount == hybridStartMinSamples {// Divide minRTT by 8 to get a rtt increase threshold for exiting.:= int64( / time.Microsecond >> hybridStartDelayFactorExp)// Ensure the rtt threshold is never less than 2ms or more than 16ms.= min(, hybridStartDelayMaxThresholdUs):= time.Duration(max(, hybridStartDelayMinThresholdUs)) * time.Microsecondif .currentMinRTT > ( + ) {.hystartFound = true}}// Exit from slow start if the cwnd is greater than 16 and// increasing delay is found.return >= hybridStartLowWindow && .hystartFound}// OnPacketSent is called when a packet was sentfunc ( *HybridSlowStart) ( protocol.PacketNumber) {.lastSentPacketNumber =}// OnPacketAcked gets invoked after ShouldExitSlowStart, so it's best to end// the round when the final packet of the burst is received and start it on// the next incoming ack.func ( *HybridSlowStart) ( protocol.PacketNumber) {if .IsEndOfRound() {.started = false}}// Started returns true if startedfunc ( *HybridSlowStart) () bool {return .started}// Restart the slow start phasefunc ( *HybridSlowStart) () {.started = false.hystartFound = false}
![]() |
The pages are generated with Golds v0.8.2. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |