Bootstrap

随机化 bbr probebw cycle phase

常打磨常新,bbr 和 inflight 守恒算法的模型和仿真也在不断优化。

再次给出 bbr 模型,这次修改了 d x d t \dfrac{dx}{dt} dtdx 的表达式,由 g 2 ⋅ x ⋅ r m i n g_2\cdot x\cdot r_{min} g2xrmin计算。同时加入了微观建模 probebw phase 的支持:

C = Bltbw,R = RtProp,T_r = ProbeRTT 周期,T 为 ProbeBW phase cycle 周期,g1 = Startup gain,g2 = ProbeBW gain。设 x = estimated bandwidth,r = round trip time,w = inflight:

g 2 ( t ) = { 1.25 , t m o d    T = 1 1 , 1 < t m o d    T ≤ T − 1 g_2(t)=\begin{cases} 1.25 ,& t\mod T=1\\\\1,&1<t\mod T\leq T-1 \end{cases} g2(t)= 1.25,1,tmodT=11<tmodTT1

I ( t ) = ∑ i = 0 n g 2 ( t + ϕ i ) ⋅ w i ( t ) I(t)=\displaystyle\sum_{i=0}^n g_2(t+\phi_i)\cdot w_i(t) I(t)=i=0ng2(t+ϕi)wi(t)

d x d t = { ( g 1 − 1 ) x , r = R C ⋅ g 2 ( t ) ⋅ x ⋅ r m i n I ( t ) − w x + g 2 ( t ) ⋅ x ⋅ r m i n − x , r > R \dfrac{dx}{dt} = \begin{cases} (g_1-1)x, & r = R \\\\ C\cdot \dfrac{g_2(t)\cdot x\cdot r_{min}}{I(t)-w_x+g_2(t) \cdot x\cdot r_{min}}-x, & r \gt R \end{cases} dtdx= (g11)x,CI(t)wx+g2(t)xrming2(t)xrminx,r=Rr>R

r ( t ) = { I ( t ) C , I ( t ) > C ⋅ R R , I ( t ) ≤ C ⋅ R r(t)=\begin{cases} \dfrac{I(t)}{C} ,& I(t)>C\cdot R\\\\R,&I(t)\leq C\cdot R \end{cases} r(t)= CI(t),R,I(t)>CRI(t)CR

r m i n = min ⁡ x ∈ [ t , t + T r ] r ( x ) r_{min}=\displaystyle\min\limits_{x\in[t,t+T_r]}r(x) rmin=x[t,t+Tr]minr(x)

d w x ( t ) d t = { x ( t ) ⋅ r m i n − w x ( t ) , t   m o d   T r ≠ 0 4 − w x ( t ) , t   m o d   T r = 0 \dfrac{dw_x(t)}{dt}=\begin{cases} x(t) \cdot r_{min}-w_x(t),& t\bmod T_r \neq 0 \\\\ 4-w_x(t),& t\bmod T_r = 0 \\ \end{cases} dtdwx(t)= x(t)rminwx(t),4wx(t),tmodTr=0tmodTr=0

这个模型描述原始的 bbr1 算法,但由于相位差的问题可能会导致不收敛(比如跌入同步 mimd):
在这里插入图片描述

bbr 充分考虑到这个问题,于是在每一轮 ProbeRTT 后会随机 place cycle phase 以打破这个局面,bbr 论文中有下列段落:

Furthermore, to improve mixing and fairness, and to reduce queues when multiple BBR flows share a bottleneck, BBR randomizes the phases of ProbeBW gain cycling by randomly picking an initial phase—from among all but the 3/4 phase—when entering ProbeBW. Why not start cycling with 3/4? The main advantage of the 3/4 pacing_gain is to drain any queue that can be created by running a 5/4 pacing_gain when the pipe is already full. When exiting Drain or ProbeRTT and entering ProbeBW, there is no queue to drain, so the 3/4 gain does not provide that advantage. Using 3/4 in those contexts only has a cost: a link utilization for that round of 3/4 instead of 1. Since starting with 3/4 would have a cost but no benefit, and since entering ProbeBW happens at the start of any connection long enough to have a Drain, BBR uses this small optimization. 【避开 0.75 印证了 dw/dt = x*R - w 这个方程的独立性和重要性】

然而原先不同步的流也可能因为这个机制而同步陷入僵局。不管怎样,这种局面一旦陷入,就要僵持一个 ProbeRTT 周期。

同步问题的万能解药就是随机。在 ProbeBW cycle 中直接用随机打破它即可。

为此,需要先做一个函数,它做如下输出,每 8 个时间单位(round-trip)随机输出且仅输出 1 次 1.25,其余输出 1:

-----cycle:0-----
phase: 0  gain: flow 1:1.00 flow 2:1.00 flow 3:1.00
phase: 1  gain: flow 1:1.00 flow 2:1.00 flow 3:1.00
phase: 2  gain: flow 1:1.00 flow 2:1.00 flow 3:1.00
phase: 3  gain: flow 1:1.00 flow 2:1.00 flow 3:1.00
phase: 4  gain: flow 1:1.00 flow 2:1.00 flow 3:1.25
phase: 5  gain: flow 1:1.00 flow 2:1.00 flow 3:1.00
phase: 6  gain: flow 1:1.25 flow 2:1.25 flow 3:1.00
phase: 7  gain: flow 1:1.00 flow 2:1.00 flow 3:1.00
-----cycle:1-----
phase: 0  gain: flow 1:1.00 flow 2:1.25 flow 3:1.00
phase: 1  gain: flow 1:1.00 flow 2:1.00 flow 3:1.00
phase: 2  gain: flow 1:1.00 flow 2:1.00 flow 3:1.00
phase: 3  gain: flow 1:1.00 flow 2:1.00 flow 3:1.00
phase: 4  gain: flow 1:1.00 flow 2:1.00 flow 3:1.00
phase: 5  gain: flow 1:1.00 flow 2:1.00 flow 3:1.00
phase: 6  gain: flow 1:1.25 flow 2:1.00 flow 3:1.25
phase: 7  gain: flow 1:1.00 flow 2:1.00 flow 3:1.00
-----cycle:2-----
phase: 0  gain: flow 1:1.00 flow 2:1.00 flow 3:1.00
phase: 1  gain: flow 1:1.00 flow 2:1.25 flow 3:1.00
phase: 2  gain: flow 1:1.00 flow 2:1.00 flow 3:1.00
phase: 3  gain: flow 1:1.00 flow 2:1.00 flow 3:1.00
phase: 4  gain: flow 1:1.25 flow 2:1.00 flow 3:1.25
phase: 5  gain: flow 1:1.00 flow 2:1.00 flow 3:1.00
phase: 6  gain: flow 1:1.00 flow 2:1.00 flow 3:1.00
phase: 7  gain: flow 1:1.00 flow 2:1.00 flow 3:1.00
-----cycle:3-----
...

以下是一个 AI 协助改出来的非常不雅观的 python 函数:

def get_value(i, seed=None):
    rng = random.Random(seed)

    cycle = i // 8
    index_within_cycle = i % 8

    if not hasattr(get_value, 'state'):
        get_value.state = {}

    if seed not in get_value.state:
        get_value.state[seed] = {
            'cycle': -1,
            'values': None,
            'rng_state': rng.getstate()
        }

    if cycle!= get_value.state[seed]['cycle']:
        rng.setstate(get_value.state[seed]['rng_state'])
        values = [1] * 8
        special_index = rng.randint(0, 7)
        values[special_index] = 1.25
        rng.shuffle(values)
        get_value.state[seed]['cycle'] = cycle
        get_value.state[seed]['values'] = iter(values)
        get_value.state[seed]['rng_state'] = rng.getstate()

    value_iter = get_value.state[seed]['values']

    try:
        value = next(value_iter)
    except StopIteration:
        rng.setstate(get_value.state[seed]['rng_state'])
        values = [1] * 8
        special_index = rng.randint(0, 7)
        values[special_index] = 1.25
        rng.shuffle(values)
        value_iter = iter(values)
        get_value.state[seed]['values'] = value_iter
        get_value.state[seed]['rng_state'] = rng.getstate()
        value = next(value_iter)

    return value

有了这个随机支持,相位差的同步僵局就解除了,即便某次不巧同步了,下一次就能解除:

    g1 = get_value(n, 1)
    g2 = get_value(n, 2)
    g3 = get_value(n, 3)
    x[n] = x[n-1] + dt * (C*g1*x[n-1]*R/(g1*x[n-1]*R + g2*wy[n-1] + g3*wz[n-1]) - x[n-1])
    y[n] = y[n-1] + dt * (C*g2*y[n-1]*R/(g2*y[n-1]*R + g1*wx[n-1] + g3*wz[n-1]) - y[n-1])
    z[n] = z[n-1] + dt * (C*g3*z[n-1]*R/(g3*z[n-1]*R + g1*wx[n-1] + g2*wy[n-1]) - z[n-1])

    wx[n] = wx[n-1] + dt * (x[n-1]*R - wx[n-1])
    wy[n] = wy[n-1] + dt * (y[n-1]*R - wy[n-1])
    wz[n] = wz[n-1] + dt * (z[n-1]*R - wz[n-1])
    r[n] = (wx[n] + wy[n] + wz[n]) / C
    if r[n] < R:
        r[n] = R

取消了相位差,效果如下:
在这里插入图片描述

浙江温州皮鞋湿,下雨进水不会胖。

;