OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/inter_arrival_sender.h" | 5 #include "net/quic/congestion_control/inter_arrival_sender.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "net/quic/congestion_control/rtt_stats.h" |
10 | 11 |
11 using std::max; | 12 using std::max; |
12 using std::min; | 13 using std::min; |
13 | 14 |
14 namespace net { | 15 namespace net { |
15 | 16 |
16 namespace { | 17 namespace { |
17 const int64 kProbeBitrateKBytesPerSecond = 1200; // 9.6 Mbit/s | 18 const int64 kProbeBitrateKBytesPerSecond = 1200; // 9.6 Mbit/s |
18 const float kPacketLossBitrateReduction = 0.7f; | 19 const float kPacketLossBitrateReduction = 0.7f; |
19 const float kUncertainSafetyMargin = 0.7f; | 20 const float kUncertainSafetyMargin = 0.7f; |
20 const float kMaxBitrateReduction = 0.9f; | 21 const float kMaxBitrateReduction = 0.9f; |
21 const float kMinBitrateReduction = 0.05f; | 22 const float kMinBitrateReduction = 0.05f; |
22 const uint64 kMinBitrateKbit = 10; | 23 const uint64 kMinBitrateKbit = 10; |
23 const int kInitialRttMs = 60; // At a typical RTT 60 ms. | |
24 const float kAlpha = 0.125f; | |
25 const float kOneMinusAlpha = 1 - kAlpha; | |
26 | 24 |
27 static const int kHistoryPeriodMs = 5000; | 25 static const int kHistoryPeriodMs = 5000; |
28 static const int kBitrateSmoothingPeriodMs = 1000; | 26 static const int kBitrateSmoothingPeriodMs = 1000; |
29 static const int kMinBitrateSmoothingPeriodMs = 500; | 27 static const int kMinBitrateSmoothingPeriodMs = 500; |
30 | 28 |
31 } // namespace | 29 } // namespace |
32 | 30 |
33 InterArrivalSender::InterArrivalSender(const QuicClock* clock) | 31 InterArrivalSender::InterArrivalSender(const QuicClock* clock, |
| 32 const RttStats* rtt_stats) |
34 : clock_(clock), | 33 : clock_(clock), |
| 34 rtt_stats_(rtt_stats), |
35 probing_(true), | 35 probing_(true), |
36 max_segment_size_(kDefaultMaxPacketSize), | 36 max_segment_size_(kDefaultMaxPacketSize), |
37 current_bandwidth_(QuicBandwidth::Zero()), | 37 current_bandwidth_(QuicBandwidth::Zero()), |
38 smoothed_rtt_(QuicTime::Delta::Zero()), | 38 smoothed_rtt_(QuicTime::Delta::Zero()), |
39 channel_estimator_(new ChannelEstimator()), | 39 channel_estimator_(new ChannelEstimator()), |
40 bitrate_ramp_up_(new InterArrivalBitrateRampUp(clock)), | 40 bitrate_ramp_up_(new InterArrivalBitrateRampUp(clock)), |
41 overuse_detector_(new InterArrivalOveruseDetector()), | 41 overuse_detector_(new InterArrivalOveruseDetector()), |
42 probe_(new InterArrivalProbe(max_segment_size_)), | 42 probe_(new InterArrivalProbe(max_segment_size_)), |
43 state_machine_(new InterArrivalStateMachine(clock)), | 43 state_machine_(new InterArrivalStateMachine(clock)), |
44 paced_sender_(new PacedSender(QuicBandwidth::FromKBytesPerSecond( | 44 paced_sender_(new PacedSender(QuicBandwidth::FromKBytesPerSecond( |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 break; | 298 break; |
299 } | 299 } |
300 bandwidth_usage_state_ = new_bandwidth_usage_state; | 300 bandwidth_usage_state_ = new_bandwidth_usage_state; |
301 } | 301 } |
302 | 302 |
303 QuicBandwidth InterArrivalSender::BandwidthEstimate() const { | 303 QuicBandwidth InterArrivalSender::BandwidthEstimate() const { |
304 return current_bandwidth_; | 304 return current_bandwidth_; |
305 } | 305 } |
306 | 306 |
307 void InterArrivalSender::UpdateRtt(QuicTime::Delta rtt) { | 307 void InterArrivalSender::UpdateRtt(QuicTime::Delta rtt) { |
308 // RTT can't be negative. | 308 state_machine_->set_rtt(rtt_stats_->SmoothedRtt()); |
309 DCHECK_LE(0, rtt.ToMicroseconds()); | |
310 | |
311 if (rtt.IsInfinite()) { | |
312 return; | |
313 } | |
314 | |
315 if (smoothed_rtt_.IsZero()) { | |
316 smoothed_rtt_ = rtt; | |
317 } else { | |
318 smoothed_rtt_ = QuicTime::Delta::FromMicroseconds( | |
319 kOneMinusAlpha * smoothed_rtt_.ToMicroseconds() + | |
320 kAlpha * rtt.ToMicroseconds()); | |
321 } | |
322 state_machine_->set_rtt(smoothed_rtt_); | |
323 } | |
324 | |
325 QuicTime::Delta InterArrivalSender::SmoothedRtt() const { | |
326 if (smoothed_rtt_.IsZero()) { | |
327 return QuicTime::Delta::FromMilliseconds(kInitialRttMs); | |
328 } | |
329 return smoothed_rtt_; | |
330 } | 309 } |
331 | 310 |
332 QuicTime::Delta InterArrivalSender::RetransmissionDelay() const { | 311 QuicTime::Delta InterArrivalSender::RetransmissionDelay() const { |
333 // TODO(pwestin): Calculate and return retransmission delay. | 312 // TODO(pwestin): Calculate and return retransmission delay. |
334 // Use 2 * the smoothed RTT for now. | 313 // Use 2 * the smoothed RTT for now. |
335 return smoothed_rtt_.Add(smoothed_rtt_); | 314 return rtt_stats_->SmoothedRtt().Multiply(2); |
336 } | 315 } |
337 | 316 |
338 QuicByteCount InterArrivalSender::GetCongestionWindow() const { | 317 QuicByteCount InterArrivalSender::GetCongestionWindow() const { |
339 return 0; | 318 return 0; |
340 } | 319 } |
341 | 320 |
342 void InterArrivalSender::EstimateNewBandwidth(QuicTime feedback_receive_time, | 321 void InterArrivalSender::EstimateNewBandwidth(QuicTime feedback_receive_time, |
343 QuicBandwidth sent_bandwidth) { | 322 QuicBandwidth sent_bandwidth) { |
344 QuicBandwidth new_bandwidth = bitrate_ramp_up_->GetNewBitrate(sent_bandwidth); | 323 QuicBandwidth new_bandwidth = bitrate_ramp_up_->GetNewBitrate(sent_bandwidth); |
345 if (current_bandwidth_ == new_bandwidth) { | 324 if (current_bandwidth_ == new_bandwidth) { |
(...skipping 28 matching lines...) Expand all Loading... |
374 } | 353 } |
375 if (estimated_congestion_delay >= back_down_congestion_delay_) { | 354 if (estimated_congestion_delay >= back_down_congestion_delay_) { |
376 // Do nothing, our estimated delay have increased. | 355 // Do nothing, our estimated delay have increased. |
377 DVLOG(1) << "Current delay estimate is higher than before draining"; | 356 DVLOG(1) << "Current delay estimate is higher than before draining"; |
378 return; | 357 return; |
379 } | 358 } |
380 DCHECK(back_down_time_.IsInitialized()); | 359 DCHECK(back_down_time_.IsInitialized()); |
381 QuicTime::Delta buffer_reduction = | 360 QuicTime::Delta buffer_reduction = |
382 back_down_congestion_delay_.Subtract(estimated_congestion_delay); | 361 back_down_congestion_delay_.Subtract(estimated_congestion_delay); |
383 QuicTime::Delta elapsed_time = | 362 QuicTime::Delta elapsed_time = |
384 feedback_receive_time.Subtract(back_down_time_).Subtract(SmoothedRtt()); | 363 feedback_receive_time.Subtract(back_down_time_).Subtract( |
| 364 rtt_stats_->SmoothedRtt()); |
385 | 365 |
386 QuicBandwidth new_estimate = QuicBandwidth::Zero(); | 366 QuicBandwidth new_estimate = QuicBandwidth::Zero(); |
387 if (buffer_reduction >= elapsed_time) { | 367 if (buffer_reduction >= elapsed_time) { |
388 // We have drained more than the elapsed time... go back to our old rate. | 368 // We have drained more than the elapsed time... go back to our old rate. |
389 new_estimate = back_down_bandwidth_; | 369 new_estimate = back_down_bandwidth_; |
390 } else { | 370 } else { |
391 float fraction_of_rate = | 371 float fraction_of_rate = |
392 static_cast<float>(buffer_reduction.ToMicroseconds()) / | 372 static_cast<float>(buffer_reduction.ToMicroseconds()) / |
393 elapsed_time.ToMicroseconds(); // < 1.0 | 373 elapsed_time.ToMicroseconds(); // < 1.0 |
394 | 374 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 void InterArrivalSender::EstimateBandwidthAfterDelayEvent( | 427 void InterArrivalSender::EstimateBandwidthAfterDelayEvent( |
448 QuicTime feedback_receive_time, | 428 QuicTime feedback_receive_time, |
449 QuicTime::Delta estimated_congestion_delay) { | 429 QuicTime::Delta estimated_congestion_delay) { |
450 QuicByteCount estimated_byte_buildup = | 430 QuicByteCount estimated_byte_buildup = |
451 current_bandwidth_.ToBytesPerPeriod(estimated_congestion_delay); | 431 current_bandwidth_.ToBytesPerPeriod(estimated_congestion_delay); |
452 | 432 |
453 // To drain all build up buffer within one RTT we need to reduce the | 433 // To drain all build up buffer within one RTT we need to reduce the |
454 // bitrate with the following. | 434 // bitrate with the following. |
455 // TODO(pwestin): this is a crude first implementation. | 435 // TODO(pwestin): this is a crude first implementation. |
456 int64 draining_rate_per_rtt = (estimated_byte_buildup * | 436 int64 draining_rate_per_rtt = (estimated_byte_buildup * |
457 kNumMicrosPerSecond) / SmoothedRtt().ToMicroseconds(); | 437 kNumMicrosPerSecond) / rtt_stats_->SmoothedRtt().ToMicroseconds(); |
458 | 438 |
459 float decrease_factor = | 439 float decrease_factor = |
460 draining_rate_per_rtt / current_bandwidth_.ToBytesPerSecond(); | 440 draining_rate_per_rtt / current_bandwidth_.ToBytesPerSecond(); |
461 | 441 |
462 decrease_factor = max(decrease_factor, kMinBitrateReduction); | 442 decrease_factor = max(decrease_factor, kMinBitrateReduction); |
463 decrease_factor = min(decrease_factor, kMaxBitrateReduction); | 443 decrease_factor = min(decrease_factor, kMaxBitrateReduction); |
464 back_down_congestion_delay_ = estimated_congestion_delay; | 444 back_down_congestion_delay_ = estimated_congestion_delay; |
465 QuicBandwidth new_target_bitrate = | 445 QuicBandwidth new_target_bitrate = |
466 current_bandwidth_.Scale(1.0f - decrease_factor); | 446 current_bandwidth_.Scale(1.0f - decrease_factor); |
467 | 447 |
468 // While in delay sensing mode send at least one packet per RTT. | 448 // While in delay sensing mode send at least one packet per RTT. |
469 QuicBandwidth min_delay_bitrate = | 449 QuicBandwidth min_delay_bitrate = |
470 QuicBandwidth::FromBytesAndTimeDelta(max_segment_size_, SmoothedRtt()); | 450 QuicBandwidth::FromBytesAndTimeDelta(max_segment_size_, |
| 451 rtt_stats_->SmoothedRtt()); |
471 new_target_bitrate = max(new_target_bitrate, min_delay_bitrate); | 452 new_target_bitrate = max(new_target_bitrate, min_delay_bitrate); |
472 | 453 |
473 ResetCurrentBandwidth(feedback_receive_time, new_target_bitrate); | 454 ResetCurrentBandwidth(feedback_receive_time, new_target_bitrate); |
474 | 455 |
475 DVLOG(1) << "New bandwidth estimate after delay event:" | 456 DVLOG(1) << "New bandwidth estimate after delay event:" |
476 << current_bandwidth_.ToKBitsPerSecond() | 457 << current_bandwidth_.ToKBitsPerSecond() << " Kbits/s min delay bitrate:" |
477 << " Kbits/s min delay bitrate:" | 458 << min_delay_bitrate.ToKBitsPerSecond() << " Kbits/s RTT:" |
478 << min_delay_bitrate.ToKBitsPerSecond() | 459 << rtt_stats_->SmoothedRtt().ToMicroseconds() << " us"; |
479 << " Kbits/s RTT:" | |
480 << SmoothedRtt().ToMicroseconds() | |
481 << " us"; | |
482 } | 460 } |
483 | 461 |
484 void InterArrivalSender::EstimateBandwidthAfterLossEvent( | 462 void InterArrivalSender::EstimateBandwidthAfterLossEvent( |
485 QuicTime feedback_receive_time) { | 463 QuicTime feedback_receive_time) { |
486 ResetCurrentBandwidth(feedback_receive_time, | 464 ResetCurrentBandwidth(feedback_receive_time, |
487 current_bandwidth_.Scale(kPacketLossBitrateReduction)); | 465 current_bandwidth_.Scale(kPacketLossBitrateReduction)); |
488 DVLOG(1) << "New bandwidth estimate after loss event:" | 466 DVLOG(1) << "New bandwidth estimate after loss event:" |
489 << current_bandwidth_.ToKBitsPerSecond() | 467 << current_bandwidth_.ToKBitsPerSecond() << " Kbits/s"; |
490 << " Kbits/s"; | |
491 } | 468 } |
492 | 469 |
493 void InterArrivalSender::ResetCurrentBandwidth(QuicTime feedback_receive_time, | 470 void InterArrivalSender::ResetCurrentBandwidth(QuicTime feedback_receive_time, |
494 QuicBandwidth new_rate) { | 471 QuicBandwidth new_rate) { |
495 new_rate = max(new_rate, | 472 new_rate = max(new_rate, |
496 QuicBandwidth::FromKBitsPerSecond(kMinBitrateKbit)); | 473 QuicBandwidth::FromKBitsPerSecond(kMinBitrateKbit)); |
497 QuicBandwidth channel_estimate = QuicBandwidth::Zero(); | 474 QuicBandwidth channel_estimate = QuicBandwidth::Zero(); |
498 ChannelEstimateState channel_estimator_state = | 475 ChannelEstimateState channel_estimator_state = |
499 channel_estimator_->GetChannelEstimate(&channel_estimate); | 476 channel_estimator_->GetChannelEstimate(&channel_estimate); |
500 | 477 |
(...skipping 29 matching lines...) Expand all Loading... |
530 if (now.Subtract(history_it->second->send_timestamp()) <= kHistoryPeriod) { | 507 if (now.Subtract(history_it->second->send_timestamp()) <= kHistoryPeriod) { |
531 return; | 508 return; |
532 } | 509 } |
533 delete history_it->second; | 510 delete history_it->second; |
534 packet_history_map_.erase(history_it); | 511 packet_history_map_.erase(history_it); |
535 history_it = packet_history_map_.begin(); | 512 history_it = packet_history_map_.begin(); |
536 } | 513 } |
537 } | 514 } |
538 | 515 |
539 } // namespace net | 516 } // namespace net |
OLD | NEW |