拥塞控制算法PCC仿真评测

 一次数据包的丢失,也许并不代表网络发生拥塞。但是在经典的tcp拥塞控制条件下,丢包作为网络拥塞信号,tcp的窗口就要减半,发送端就要减少向网络中发送的数据包数量。
 若是丢包是如下原因,降窗明显不合理。

  • f might traverse a shallow buffer on a high-BDP link, with the loss due to bad luck in statistical multiplexing rather than high link utilization.
  • There may be a higher-rate competing flow.
  • There may be random non-congestion loss somewhere along the path such as noise packet loss.

 关键的就是PCC的速率控制机制了,这个机制和后来出现的BBR算法几乎相同,增加发送速率对网络带宽进行探测。PCC按照监测周期(MI,Monitor Interval)更改发送速率,每四个MI形成两个对。在每个监测对中,分别按照速率 ( 1 + ϵ ) r (1+\epsilon)r (1+ϵ)r, ( 1 − ϵ ) r (1-\epsilon)r (1ϵ)r向网络中发包。四个监测周期后,速率更改为 r r r,发送端等待反馈的ack,分别计算相应监测周期的效用函数 ( U i + , U i − , i = 1 , 2 ) (U_i^+,U_i^-,i=1,2) (Ui+,Ui,i=1,2)。如果 U i + > U i − , ∀ i ∈ { 1 , 2 } U_i^+>U_i^-,\forall i\in\{1,2\} Ui+>Ui,i{1,2},则将发送速率调整为 ( 1 + ϵ ) r (1+\epsilon)r (1+ϵ)r;如果 U i + < U i − , ∀ i ∈ { 1 , 2 } U_i^+Ui+<Ui,i{1,2},则将发送速率调整为 ( 1 − ϵ ) r (1-\epsilon)r (1ϵ)r;若是其他情况,则保持当前的速率。
 其采用的效用函数如下:
u i ( x ) = T i ( x ) s i g m o i d ( L i ( x ) − 0.05 ) − x i ( t ) L i ( t ) (1) u_i(x)=T_i(x)sigmoid(L_i(x)-0.05)-x_i(t)L_i(t)\tag{1} ui(x)=Ti(x)sigmoid(Li(x)0.05)xi(t)Li(t)(1)
x i ( t ) x_i(t) xi(t)为数据包发送速率, L i ( t ) L_i(t) Li(t)为丢包率, T i ( x ) = x i ( t ) ( 1 − L i ( x ) ) T_i(x)=x_i(t)(1-L_i(x)) Ti(x)=xi(t)(1Li(x))为吞吐量,当丢包率超过0.05, u i ( x ) u_i(x) ui(x)为负,可以认为此时的网络状况极其糟糕。
 这个算法,有缺点,带宽小的数据流竞争带宽慢,收敛速度较慢。但是保证了链路的利用率高。另外一个缺点,就是发送速率不太稳定,就是因为它的速率总是为效用函数取得最大的值,这个看下论文[3]中的图例。
 我把[4]的代码,移植到ns3仿真平台,对算法性能性能进行测试。
 只使用一条链路,两个点,链路配置(5Mbps, 50ms单向时延,5Mbps*100ms的缓冲区)。一个测试五条数据流,各个数据流进入网络中的时刻不同。
 各个数据流的带宽变化情况:
拥塞控制算法PCC仿真评测_第1张图片
 带宽公平性有保证,发送速率抖动明显。
 接收数据包的单向传输时延变化,仅画出数据流1:
拥塞控制算法PCC仿真评测_第2张图片
 我的拥塞控制分析文章,一般是在3M带宽的链路中进行测试,使用三条数据流。这次例外,因为,我在3M链路上测试时,发现第一条流的发送速率超出了链路带宽很多,这个算法有不稳定的情况。可能是效用函数的定义问题,懒得花时间去分析具体原因了,没有收益。
 [4]代码中的效用函数的实现同论文中的定义有很大不同。

double PccUtilityFunction::CalculateUtility(const MonitorInterval* interval) const{
  // The caller should guarantee utility of this interval is available.
  QUIC_BUG_IF(interval->first_packet_sent_time ==
              interval->last_packet_sent_time);

  // Add the transfer time of the last packet in the monitor interval when
  // calculating monitor interval duration.
  double interval_duration =
      static_cast((interval->last_packet_sent_time -
                              interval->first_packet_sent_time +
                              interval->sending_rate
                                  .TransferTime(kMaxV4PacketSize))
                             .ToMicroseconds());

  double rtt_ratio =
      static_cast(interval->rtt_on_monitor_start.ToMicroseconds()) /
      static_cast(interval->rtt_on_monitor_end.ToMicroseconds());
  if (rtt_ratio > 1.0 - interval->rtt_fluctuation_tolerance_ratio &&
      rtt_ratio < 1.0 + interval->rtt_fluctuation_tolerance_ratio) {
    rtt_ratio = 1.0;
  }
  double latency_penalty =
      1.0 - 1.0 / (1.0 + exp(kRTTCoefficient * (1.0 - rtt_ratio)));

  double bytes_acked = static_cast(interval->bytes_acked);
  double bytes_lost = static_cast(interval->bytes_lost);
  double bytes_sent = static_cast(interval->bytes_sent);
  double loss_rate = bytes_lost / bytes_sent;
  double loss_penalty =
      1.0 - 1.0 / (1.0 + exp(kLossCoefficient * (loss_rate - kLossTolerance)));

  return (bytes_acked / interval_duration * loss_penalty * latency_penalty -
      bytes_lost / interval_duration) * 1000.0;
}

 这个不正常的仿真结果(链路带宽3Mbps),也放在这里吧。
拥塞控制算法PCC仿真评测_第3张图片
 这里的仿真结果,大致看一下吧。PCC里面的思想还是不错的,不知道后续的BBR的拥塞控制是不是也从PCC中获取了一定的灵感。
 测试下PCC Vivace[5]在3M链路中的表现吧。效用函数以及相关参数的实现来自webrtc的实现。
 Vivace数据流的发送速率变化情况:
拥塞控制算法PCC仿真评测_第4张图片
 Vivace数据流的接收数据包单向传输时延变化:
拥塞控制算法PCC仿真评测_第5张图片
 也可以参考斯坦福学生,在课程cs244,对PCC的评测,有同学把它翻译成了中文[6]
[1] PCC: Re-architecting Congestion Control for Consistent High Performance
[2] 拥塞控制算法分类
[3] statistical learning based congestion control for real-time video communication
[4] PCC code
[5] PCC Vivace: Online-Learning Congestion Control
[6] PCC-244 翻译

你可能感兴趣的:(拥塞控制)