TCP BIC 拥塞控制源码分析

本文深入探讨了BIC算法在TCP协议带宽估计中的应用,通过二分查找技术准确快速地估计带宽。分析了BIC算法在不同场景下的探测逻辑,并详细解释了其核心参数的意义及作用。

    1、对于TCP协议数据传输优化来说最大的难点就在于物理带宽的估计,网络的复杂性决定了拥塞控制算法作用的有限性和Linux内核支持的拥塞控制算法(reno、newreno、hybla、bic、cubic、westwood、vegas、yeah等)的多样性,只有准确的带宽估计才能够充分的利用带宽,所以当前的主要难点是带宽估计。

    2、BIC 主要用来解决高速大延时网络(High-speed networks with large delays)的带宽估计问题。

    3、BIC算法其实是看透了带宽探测、估计的过程,所以其使用了二分查找技术来准确、快速的估计带宽。



BIC二分查找逻辑分析:

    如上图,横轴是last_max_cwnd,意义是上次丢包时预估的带宽值,这个值将对下一轮的带宽估计起着关键影响,纵坐标是snd_cwnd,这幅图描述的是BIC在拥塞避免阶段的snd_cwnd调节。  

    带宽逼近过程(snd_cwnd < last_max_cwnd):     

         1、dist = last_max_cwnd - snd_cwnd:

         2、dist < A,snd_cwnd快逼近带宽值预估值了,snd_cwnd的探测速度要放慢,否则可能会出现丢包。

         3、A < dist < B,那么此时应该将snd_cwnd探测速度调节到适中值。

         4、dist > B,snd_cwnd离last_max_cwnd距离很远,需要加快它的探测速度。

 

    新带宽探测过程(snd_cwnd > last_max_cwnd):

         1、dist = last_max_cwnd - snd_cwnd:

         2、如果 dist < C,那么需要慢速探测;

         3、如果 C < dist < D,那么中速探测;

         4、如果 dist > D,那么应该快速探测。


/* BIC TCP Parameters */
struct bictcp {
	u32	cnt;		/* increase cwnd by 1 after ACKs */
	u32 	last_max_cwnd;	/* last maximum snd_cwnd */
	u32	loss_cwnd;	/* congestion window at last loss */
	u32	last_cwnd;	/* the last snd_cwnd */
	u32	last_time;	/* time when updated last_cwnd */
	u32	epoch_start;	/* beginning of an epoch */
#define ACK_RATIO_SHIFT	4
	u32	delayed_ack;	/* estimate the ratio of Packets/ACKs << 4 */
};

   u32cnt; /* increase cwnd by 1 after ACKs */

     用来记录进入拥塞避免状态后,需要接收到多少个ACK才能出发snd_cwnd + 1

   u32  last_max_cwnd;/* last maximum snd_cwnd */

      丢包的时候,BIC需要选取一个snd_cwnd值作为二分查找的上限值,如果当前二分查找的带宽值大于上一次丢包记录的last_max_cwnd那么last_max_cwnd更新为当前的snd_cwnd,否则为0.9 * snd_cwnd,关于这个问题其实很好理解,如果当前探测到的带宽值比设定的二分阈值小,那么说明当前带宽比之前预计的带宽要小,所以下次预测带宽值要缩小,缩小为原来的0.9倍。

   u32 loss_cwnd; /* congestion window at last loss */

     用来记录丢包时的拥塞窗口值。

   u32 last_time;/* time when updated last_cwnd */

      用来记录最近一次拥塞避免阶段snd_cwnd调节的timestamp,如果多次进入时间差很小那么只会调节一次,避免频繁的调节。

   u32	epoch_start;	/* beginning of an epoch */

     用来记录计入拥塞避免状态的timestamp,这个变量在BIC拥塞控制算法具体实现中,没有太大意义。

<span style="font-size:14px;">   </span><span style="font-size:18px;">u32	delayed_ack;	/* estimate the ratio of Packets/ACKs << 4 */</span>

   用来记录延时ACK的个数,BIC考虑的延时ACK对带宽估计的影响。

/*
 * Compute congestion window to use.
 */
static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
{
	if (ca->last_cwnd == cwnd &&
	    (s32)(tcp_time_stamp - ca->last_time) <= HZ / 32)
		return;

	ca->last_cwnd = cwnd;
	ca->last_time = tcp_time_stamp;

	if (ca->epoch_start == 0) /* record the beginning of an epoch */
		ca->epoch_start = tcp_time_stamp;

	/* start off normal */
	if (cwnd <= low_window) {
		ca->cnt = cwnd;
		return;
	}

	/* binary increase */
	if (cwnd < ca->last_max_cwnd) {
		__u32 	dist = (ca->last_max_cwnd - cwnd)
			/ BICTCP_B;

		if (dist > max_increment)
			/* linear increase */
			ca->cnt = cwnd / max_increment;
		else if (dist <= 1U)
			/* binary search increase */
			ca->cnt = (cwnd * smooth_part) / BICTCP_B;
		else
			/* binary search increase */
			ca->cnt = cwnd / dist;
	} else {
		/* slow start AMD linear increase */
		if (cwnd < ca->last_max_cwnd + BICTCP_B)
			/* slow start */
			ca->cnt = (cwnd * smooth_part) / BICTCP_B;
		else if (cwnd < ca->last_max_cwnd + max_increment*(BICTCP_B-1))
			/* slow start */
			ca->cnt = (cwnd * (BICTCP_B-1))
				/ (cwnd - ca->last_max_cwnd);
		else
			/* linear increase */
			ca->cnt = cwnd / max_increment;
	}

	/* if in slow start or link utilization is very low */
	if (ca->loss_cwnd == 0) {
		if (ca->cnt > 20) /* increase cwnd 5% per RTT */
			ca->cnt = 20;
	}

	ca->cnt = (ca->cnt << ACK_RATIO_SHIFT) / ca->delayed_ack;
	if (ca->cnt == 0)			/* cannot be zero */
		ca->cnt = 1;
}
### TCP四大拥塞控制算法的源码实现 #### Reno算法 Reno算法作为经典的TCP拥塞控制算法,在Linux内核源码中的`tcp_cong.c`文件中有其实现。核心逻辑位于函数`tcp_reno_cong_avoid`之中,此函数负责判断当前应处于慢启动阶段还是拥塞避免阶段,并据此调整发送窗口大小。通过修改特定代码片段可改变其行为模式,例如设置发送窗口为`snd_cwnd_clamp/4`[^3]。 ```cpp // 修改后的Reno算法部分代码示例 if (condition) { tp->snd_cwnd = tp->snd_cwnd_clamp / 4; } ``` #### BIC算法 BIC(Binary Increase Congestion Control)是一种改进型的拥塞控制策略,旨在提高高带宽延迟乘积环境下的性能表现。其工作原理基于二分搜索的思想来寻找最优发送速率。具体流程涉及多个子过程协同作用以达成目标[^2]。 #### CUBIC算法 CUBIC是对BIC的发展和完善版本,同样适用于现代互联网条件。它采用三次方程模型预测最佳cwnd增长曲线,从而更好地适应快速变化的网络状况并减少波动影响。虽然未直接提及源码位置,但在实际应用中通常会替换掉默认的Reno或其他传统方案成为新的标准配置选项之一。 #### BBR算法 BBR(Bottleneck Bandwidth and Round-trip propagation time)代表了一种全新的设计理念——即不依赖于丢包信号而是主动探测链路特性来进行流量调控。这意味着即使在网络非常稳定的情况下也能充分利用可用资源而不必等待错误发生才做出反应;而且一旦检测到瓶颈则立即采取措施防止过载现象的发生。在整个过程中,BBR独立决定了每次能够发送的数据量而无需遵循传统的四态机状态转换规则约束[^4]。 ```python def bbr_algorithm(): while True: # 主动测量路径最大容量与往返时间 bandwidth = measure_bandwidth() rtt = measure_rtt() # 计算理想发送率 ideal_rate = calculate_ideal_rate(bandwidth, rtt) # 调整发送窗口至理想值附近 adjust_window(ideal_rate) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值