| 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 |