OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/congestion_control/hybrid_slow_start.h" | 5 #include "net/quic/congestion_control/hybrid_slow_start.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 using std::max; | 9 using std::max; |
10 using std::min; | 10 using std::min; |
11 | 11 |
12 namespace net { | 12 namespace net { |
13 | 13 |
14 // Note(pwestin): the magic clamping numbers come from the original code in | 14 // Note(pwestin): the magic clamping numbers come from the original code in |
15 // tcp_cubic.c. | 15 // tcp_cubic.c. |
16 const int64 kHybridStartLowWindow = 16; | 16 const int64 kHybridStartLowWindow = 16; |
17 // Number of delay samples for detecting the increase of delay. | 17 // Number of delay samples for detecting the increase of delay. |
18 const uint32 kHybridStartMinSamples = 8; | 18 const uint32 kHybridStartMinSamples = 8; |
19 const int kHybridStartDelayFactorExp = 4; // 2^4 = 16 | 19 const int kHybridStartDelayFactorExp = 4; // 2^4 = 16 |
20 // The original paper specifies 2 and 8ms, but those have changed over time. | 20 // The original paper specifies 2 and 8ms, but those have changed over time. |
21 const int64 kHybridStartDelayMinThresholdUs = 4000; | 21 const int64 kHybridStartDelayMinThresholdUs = 4000; |
22 const int64 kHybridStartDelayMaxThresholdUs = 16000; | 22 const int64 kHybridStartDelayMaxThresholdUs = 16000; |
23 | 23 |
24 HybridSlowStart::HybridSlowStart(const QuicClock* clock) | 24 HybridSlowStart::HybridSlowStart(const QuicClock* clock) |
25 : clock_(clock), | 25 : clock_(clock), |
| 26 ack_train_detection_(true), |
26 started_(false), | 27 started_(false), |
27 hystart_found_(NOT_FOUND), | 28 hystart_found_(NOT_FOUND), |
28 last_sent_sequence_number_(0), | 29 last_sent_sequence_number_(0), |
29 round_start_(QuicTime::Zero()), | 30 round_start_(QuicTime::Zero()), |
30 end_sequence_number_(0), | 31 end_sequence_number_(0), |
31 last_close_ack_pair_time_(QuicTime::Zero()), | 32 last_close_ack_pair_time_(QuicTime::Zero()), |
32 rtt_sample_count_(0), | 33 rtt_sample_count_(0), |
33 current_min_rtt_(QuicTime::Delta::Zero()) { | 34 current_min_rtt_(QuicTime::Delta::Zero()) { |
34 } | 35 } |
35 | 36 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 } | 78 } |
78 QuicTime current_time = clock_->ApproximateNow(); | 79 QuicTime current_time = clock_->ApproximateNow(); |
79 | 80 |
80 // First detection parameter - ack-train detection. | 81 // First detection parameter - ack-train detection. |
81 // Since slow start burst out packets we can indirectly estimate the inter- | 82 // Since slow start burst out packets we can indirectly estimate the inter- |
82 // arrival time by looking at the arrival time of the ACKs if the ACKs are | 83 // arrival time by looking at the arrival time of the ACKs if the ACKs are |
83 // spread out more then half the minimum RTT packets are being spread out | 84 // spread out more then half the minimum RTT packets are being spread out |
84 // more than the capacity. | 85 // more than the capacity. |
85 // This first trigger will not come into play until we hit roughly 9.6 Mbps | 86 // This first trigger will not come into play until we hit roughly 9.6 Mbps |
86 // with delayed acks (or 4.8Mbps without delayed acks) | 87 // with delayed acks (or 4.8Mbps without delayed acks) |
87 // TODO(ianswett): QUIC always uses delayed acks, even at the beginning, so | 88 if (ack_train_detection_ && |
88 // this should likely be at least 4ms. | 89 current_time.Subtract(last_close_ack_pair_time_).ToMicroseconds() <= |
89 // TODO(pwestin): we need to make sure our pacing don't trigger this detector. | |
90 // TODO(ianswett): Pacing or other cases could be handled by checking the send | |
91 // time of the first acked packet in a receive round. | |
92 if (current_time.Subtract(last_close_ack_pair_time_).ToMicroseconds() <= | |
93 kHybridStartDelayMinThresholdUs) { | 90 kHybridStartDelayMinThresholdUs) { |
94 last_close_ack_pair_time_ = current_time; | 91 last_close_ack_pair_time_ = current_time; |
95 if (current_time.Subtract(round_start_).ToMicroseconds() >= | 92 if (current_time.Subtract(round_start_).ToMicroseconds() >= |
96 min_rtt.ToMicroseconds() >> 1) { | 93 min_rtt.ToMicroseconds() >> 1) { |
97 hystart_found_ = ACK_TRAIN; | 94 hystart_found_ = ACK_TRAIN; |
98 } | 95 } |
99 } else if (last_close_ack_pair_time_ == round_start_) { | 96 } else if (last_close_ack_pair_time_ == round_start_) { |
100 // If the previous ack wasn't close, then move forward the round start time | 97 // If the previous ack wasn't close, then move forward the round start time |
101 // to the incoming ack. | 98 // to the incoming ack. |
102 last_close_ack_pair_time_ = round_start_ = current_time; | 99 last_close_ack_pair_time_ = round_start_ = current_time; |
(...skipping 26 matching lines...) Expand all Loading... |
129 hystart_found_= DELAY; | 126 hystart_found_= DELAY; |
130 } | 127 } |
131 } | 128 } |
132 // Exit from slow start if the cwnd is greater than 16 and an ack train or | 129 // Exit from slow start if the cwnd is greater than 16 and an ack train or |
133 // increasing delay are found. | 130 // increasing delay are found. |
134 return congestion_window >= kHybridStartLowWindow && | 131 return congestion_window >= kHybridStartLowWindow && |
135 hystart_found_ != NOT_FOUND; | 132 hystart_found_ != NOT_FOUND; |
136 } | 133 } |
137 | 134 |
138 } // namespace net | 135 } // namespace net |
OLD | NEW |