zoukankan      html  css  js  c++  java
  • TCP拥塞控制算法内核实现剖析(七)

    内核版本:3.2.12

    主要源文件:linux-3.2.12/ net/ ipv4/ tcp_scalable.c

    本文主要分析scalable的实现,作者zhangskd @ csdn
    ====================================================================================

    原理

    The design objective of STCP is to make the recovery time from loss events be constant regardless of

    the window size. This is why it is called "Scalable". Note that the recovery time of TCP-NewReno largely

    depends on the current window size.

    STCP suggests alternative algorithms for cwnd increase and decrease(in congestion avoidance).

    主要算法:

    cwnd = cwnd + 0.01 (per ACK received in an RTT)

    Upon the first detection of congestion, the cwnd is decreased accordingly.

    cwnd = cwnd - (0.125*cwnd)

    Scalable算法:主要改进了AIMD。尤其是AI,由于AI为一个常数,故其快速恢复后,恢复到峰值所用的时间

    只跟RTT有关。

    数据结构

    /* These factors derived from the recommended values in the aer:
     * 0.1 and 7/8. We use 50 instend of 100 to account for delayed ack.
     */
    #define TCP_SCALABLE_AI_CNT 50U
    #define TCP_SCALABLE_MD_SCALE 3

    由于delayed ack的使用,通常发送2个数据包才返回一个ack。所以,把cnt = 100改为cnt = 50。如此一来,

    相当于每发送100个数据包snd_cwnd就加1。

    函数

    static void tcp_scalable_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
    {
        struct tcp_sock *tp = tcp_sk(sk);
        if (!tcp_is_cwnd_limited(sk, in_flight))
            return;
    
        if (tp->snd_cwnd <= tp->snd_ssthresh)
            tcp_slow_start(tp);
        else
            /* 当snd_cwnd < 50时,同Reno.*/
            tcp_cong_avoid_ai(tp, min(tp->snd_cwnd, TCP_SCALABLE_AI_CNT));
    }
    static u32 tcp_scalable_ssthresh(struct sock *sk)
    {
        const struct tcp_sock *tp = tcp_sk(sk);
        /* 减小因子为 1/8 */
        return max(tp->snd_cwnd - (tp->snd_cwnd >> TCP_SCALABLE_MD_SCALE), 2U);
    }

    性能

    可以看出Scalable的原理和实现都比较简单,但是,它有一个很有特色的地方,就是在丢包并快速恢复后,

    从再次进入拥塞避免到达到上次丢包时的cwnd,Scalable所用的时间只跟RTT有关!

    我们先来看以下Reno:

    假设在发生丢包时的cwnd为C,那么再次进入拥塞避免时的cwnd=C/2.

    由于每个RTT内cwnd加1,所以cwnd从C/2恢复到C需要的时间为:(C/2) * RTT

    可见,Reno从再次进入拥塞避免,到恢复到丢包前的cwnd所需要的时间不仅和RTT有关,还和C成正比。

    也就是说,当C越大,耗时就越多。在BDP网络中,这是不可以接受的。

    对于Scalable:

    cwnd(k+1) = cwnd(k) + cwnd(k) / 100

    在发生丢包时的cwnd=C,那么再次进入拥塞避免时的cwnd=0.875C.

    假设从0.875C恢复到C需要n个RTT的时间。

    那么:0.875C(1+0.01)^n = C

    所以 n = -log(0.875) / log(1+0.01) = 14

    可以看到,不管C是多少,恢复的时间都是14*RTT!在较大的BDP中,Scalable节省的时间就很可观了。

    不足:Scalable的Convergence(收敛性)不好,不能很好地处理多条连接共存的情况。

  • 相关阅读:
    Windows 10+Ubuntu 16.04在MBR分区上安装双系统(转)
    安装Ubuntu 16.04时出现:没有定义根文件系统,请到分区菜单修改
    Windows 10+Ubuntu 16.04在MBR分区上安装双系统之后启动菜单的System Setup选项提示:can't find command "fwsetup"
    Ubuntu 16.04安装GTX960闭源驱动
    Windows 10+Ubuntu 16.04在MBR分区上安装双系统之后没有Windows 10的启动菜单解决方法
    Ubuntu16.04安装deb文件时提示:此软件来自第三方且可能包含非自由组件
    完全卸载SQL Server 2008 R2(转)
    Windows超级卸载工具Total Uninstaller,能完全卸载.NET Framework
    Windows 10卸载Edge浏览器(不成功的别试了)
    完全卸载VS2015的方法
  • 原文地址:https://www.cnblogs.com/aiwz/p/6333388.html
Copyright © 2011-2022 走看看