skywind3000 / kcp

:zap: KCP - A Fast and Reliable ARQ Protocol
MIT License
15.2k stars 2.49k forks source link

关于源码中的慢启动和拥塞避免算法 #402

Open yufeige4 opened 10 months ago

yufeige4 commented 10 months ago

下面代码中,在慢启动条件下(cwnd<sstresh),为什么窗口大小是线性增长而非指数级增长,而在非慢启动条件下却是指数级增长,是不是写反了: ` // 收到了未确认过的数据包 if (_itimediff(kcp->snd_una, prev_una) > 0) { if (kcp->cwnd < kcp->rmt_wnd) { // 本地窗口大小小于远程窗口 IUINT32 mss = kcp->mss; if (kcp->cwnd < kcp->ssthresh) { // 慢启动 kcp->cwnd++; kcp->incr += mss; } else { // incr最小值为一个单元的数据大小 if (kcp->incr < mss) { kcp->incr = mss; } // 指数级增长 kcp->incr += (mss mss) / kcp->incr + (mss / 16); if ((kcp->cwnd + 1) mss <= kcp->incr) {

if 1

                kcp->cwnd = (kcp->incr + mss - 1) / ((mss > 0)? mss : 1);
            #else
                kcp->cwnd++;
            #endif
            }
        }
        // 不超过远程窗口大小
        if (kcp->cwnd > kcp->rmt_wnd) {
            kcp->cwnd = kcp->rmt_wnd;
            kcp->incr = kcp->rmt_wnd * mss;
        }
    }
}`
yufeige4 commented 10 months ago

所以是不是慢启动策略采用了线性增长,而常规阶段使用近似于对数级增长。

lingzhiShen commented 7 months ago

慢启动阶段是线性增长,超过了ssthresh阈值后kcp->incr += (mss * mss) / kcp->incr + (mss / 16);每16个UNA确认增长一个mss,并且随着kcp->incr越大,增长速度越慢,每次增长区间(mss/16 ~ mss+mss/16],小于线性增长。

logincat commented 7 months ago

在《计算机网络》谢希仁老师著中,慢启动算法是指数增加,而超过门限值之后,就采用拥塞避免算法,拥塞避免算法在其书中是线性增加的,理论上确实会存在边际效用,当你发送窗口已经很大时,应该谨慎增加,否则冲突时,丢掉的数据就多,影响面更大。