Hybrid Slow Start混合慢啟動(dòng)算法

傳統(tǒng)的單純采用指數(shù)增長(zhǎng)的慢啟動(dòng)算法有一個(gè)無法避免的問題,在臨界進(jìn)入擁塞避免階段時(shí),特別是在高帶寬長(zhǎng)距離網(wǎng)絡(luò)中,容易出現(xiàn)大規(guī)模丟包,進(jìn)而導(dǎo)致大量數(shù)據(jù)包重傳,也有可能出現(xiàn)timeout,致使網(wǎng)絡(luò)帶寬利用率下降。
??這里,本文將介紹一種新的慢啟動(dòng)方法——Hybrid Slow Start,它在傳統(tǒng)的慢啟動(dòng)算法中加入了判斷機(jī)制,強(qiáng)制從慢啟動(dòng)轉(zhuǎn)入擁塞避免。這里主要說說其在CUBIC中是怎么實(shí)現(xiàn)的,Hybrid Slow Start算法原理本身就不做過多介紹了,有興趣可以看看本文最后給出的參考文獻(xiàn)。

變量介紹

#define HYSTART_ACK_TRAIN      0x1 //進(jìn)入擁塞避免的條件
#define HYSTART_DELAY          0x2 //進(jìn)入擁塞避免的條件
#define HYSTART_MIN_SAMPLES    8   //表示至少取一個(gè)RTT的前8個(gè)ACK作為樣本
#define HYSTART_DELAY_MIN      (4u<<3) 
#define HYSTART_DELAY_MAX      (16u<<3)
/* if x > HYSTART_DELAY_MAX,return HYSTART_DELAY_MAX 
 * else if x < HYSTART_DELAY_MIN,return HYATART_DELAY_MIN
 * else return x
 */
#define HYSTART_DELAY_THRESH clamp(x, HYSTART_DELAY_MIN, HYSTART_DELAY_MAX)
static int hystart __read_mostly = 1;
static int hystart_detect __read_mostly = HYSTART_ACK_TRAIN | HYSART_DELAY;
static int hystart_low_window __read_mostly = 16;
static int hystart_ack_delta __read_mostly = 2;

struct bictcp {
  ...
  u32    delay_min;   //全局最小rtt
  u32    round_start; //記錄慢啟動(dòng)的起始時(shí)間
  u32    curr_rtt;    //記錄樣本中的最小rtt
  u8      found;
  u8      sample_cnt; //樣本計(jì)數(shù)變量
  ...
};

兩類退出slow start機(jī)制

在Hybrid Slow Start算法中給出了種類判斷機(jī)制用來退出慢啟動(dòng)進(jìn)入擁塞避免,分別是ACKs train length和Increase in packet delays。

ACKS train length

這里給出一段原文描述,在這段描述中說了怎么測(cè)ACKs train length以及為什么要用ACKs train length。

The ACK train length is measured by calculating the sum of inter-arrival times of all the closely spaced ACKs within an RTT round. The train length is strongly affected by the bottleneck bandwidth, routing delays and buffer sizes along the path, and is easily stretched out by congestion caused by cross traffic in the path, so by estimating the train length we can reliably find a safe exit point of Slow Start.

Increase in packet delays

同樣還是一段原文描述,如果你問我為什么不直接翻譯成中文,我不會(huì)回答你這個(gè)問題的。

Increase in packet delays during Slow Start may indicate the possibility of the bottleneck router being congested.

但是Increase in packet delays的測(cè)量會(huì)受到bursty transmission的影響,所以只測(cè)一個(gè)RTT中剛開始的幾個(gè)數(shù)據(jù)包的往返時(shí)間來避免bursty transission的影響,在后面給出的code中會(huì)看到。

函數(shù)實(shí)現(xiàn)

hystart重置函數(shù)

static inline void bictcp_hystart_reset(struct sock *sk)
{
    struct tcp_sock *tp = tcp_sk(sk);
    struct bictcp *ca = inet_csk_ca(sk);
    
    ca->round_start = ca->last_ack = bictcp_clock(); //記錄慢啟動(dòng)的開始時(shí)間
    ca->end_seq = tp->snd_nxt;
    ca->curr_rtt = 0;   //重置樣本最小rtt為0
    ca->sample_cnt = 0; //重置樣本計(jì)數(shù)為0
}

Hybrid Slow Start實(shí)現(xiàn)的核心部分

static void hystart_update(struct sock *sk, u32 delay)
{
    struct tcp_sock *tp = tcp_sk(sk);
    struct bictcp *ca = inet_csk_ca(sk);

    //如果ca->found & hystart_detect為真,表示應(yīng)該進(jìn)入擁塞避免
    if (!(ca->found & hystart_detect)) {
        u32 now = bictcp_clock(); //獲取當(dāng)前時(shí)間

        /* first detection parameter - ack-train detection */
        /* 前后到來的兩個(gè)ACK的間隔時(shí)間小于hystart_ack_delta才有效 */
        if ((s32)(now - ca->last_ack) <= hystart_ack_delta) {
            ca->last_ack = now;  //更新上一個(gè)ACK到來的時(shí)間
            /* 每次慢啟動(dòng)時(shí)會(huì)重置round_start為0,結(jié)合前面的if條件,下面的
             * if成立的條件是:從慢啟動(dòng)開始到現(xiàn)在經(jīng)過的時(shí)間如果大于
             * delay_min>>4,那么可以進(jìn)入擁塞避免了。至于為什么選
             * delay_min>>4這個(gè)值,鬼知道。
             */
            if ((s32)(now - ca->round_start) > ca->delay_min >> 4)
                ca->found |= HYSTART_ACK_TRAIN;
        }   

        /* obtain the minimum delay of more than sampling packets */
        /* 如果樣本計(jì)數(shù)小于HYSTART_MIN_SAMPLES(默認(rèn)為8) */
        if (ca->sample_cnt < HYSTART_MIN_SAMPLES) {
            if (ca->curr_rtt == 0 || ca->curr_rtt > delay)
                ca->curr_rtt = delay;/* 更新樣本中的最小rtt */

            ca->sample_cnt++;
        } else {//如果樣本大于8了,那么就可以判斷是否要進(jìn)入擁塞避免了
            /* 如果前面8個(gè)樣本中的最小rtt大于全局最小rtt與閾值的和,那么表示網(wǎng)絡(luò)出
             * 現(xiàn)了擁塞,應(yīng)立馬進(jìn)入擁塞避免階段,HYSTART_DELAY_THRESH()的返
             * 回值在前面的變量介紹中有說明。
            if (ca->curr_rtt > ca->delay_min +
                HYSTART_DELAY_THRESH(ca->delay_min>>4))
                ca->found |= HYSTART_DELAY;
        }   
        /*  
         * Either one of two conditions are met,
         * we exit from slow start immediately.
         */
        /* 如果為真就進(jìn)入擁塞避免 */
        if (ca->found & hystart_detect)
            tp->snd_ssthresh = tp->snd_cwnd;
    }   
}

最近做實(shí)驗(yàn)需要探測(cè)網(wǎng)絡(luò)帶寬,需要用到Hybrid Slow Start,所以看了paper和其在Linux CUBIC算法中的實(shí)現(xiàn),然后就寫了這篇blog。
參考文獻(xiàn):Hybrid Slow Start for High-Bandwidth and Long-Distance Networks

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 文/蔥蔥 早上出小區(qū),走在上班的路上,突然聽見120救護(hù)車高嚷著飛快行駛在馬路上,心里正琢磨著可能是小區(qū)某戶人家的...
    蔥蔥_閱讀 835評(píng)論 12 11
  • 上次說了最近瘦身的見證,其實(shí)自從心里不匱乏了開始,突然感覺不餓了,今天又去吸引了健身卡! 其實(shí)我超級(jí)討厭運(yùn)動(dòng)...
    貓公主喵閱讀 124評(píng)論 0 2
  • 從深圳到廣州 這個(gè)距離 417等了兩
    cy_chan閱讀 202評(píng)論 0 0
  • 就像個(gè)默默無聞的教徒,做了自己覺得所有應(yīng)該做的事,卻還是任由上帝宰割。毫無還擊之力。當(dāng)人力無法掌控的時(shí)候,就開始相...
    果綠a閱讀 372評(píng)論 0 0

友情鏈接更多精彩內(nèi)容