来看一个极简的拥塞控制实现 net/ipv4/tcp_scalable.c,去掉注释不到 50 行代码。它的介绍在 Scalable TCP-improving performance in highspeed networks。由于太简单,估计没什么人会在意。
本文说一下它背后的道理。
无论 bic/cubic,westwood,还是 scalable,都是针对 reno 的优化,reno 是大道,是本质,其它这些是针对长肥管道的拓展。reno tcp 的 aimd 过程很简单,每收到一个 ack(不考虑 ack 聚集和 delayed ack) 以及丢包时的行为如下:
w = w + 1 R T T w=w+\dfrac{1}{RTT} w=w+RTT1
w = w − 0.5 ⋅ w w=w-0.5\cdot w w=w−0.5⋅w
而 scalable tcp 更新为如下:
w = w + 0.01 w=w+0.01 w=w+0.01
w = w − 0.125 ⋅ w w=w-0.125\cdot w w=w−0.125⋅w
这么一个微小的改动,取消了 rtt 相关性,与 cubic 无异,但它到底 scalable 在哪,先来一个总体观感,先看 reno 和 scalable 分别在 rtt 10,20,50,100 的共存收敛:
随 rtt 的增加,管道不断变长,scalable tcp 的优势逐渐体现,当 rtt 巨大时,将 reno tcp 彻底压制,但在 rtt 很小时,reno tcp 体现出优势。这个结果的原因可从下图解释:
reno tcp 的锯齿随着 rtt 增加而变钝,scalable tcp 与 rtt 无关,万年不变。这意味着:
- 更慢的增长期应对丢包 md 的代价更大;
- 更大的 md 系数使锯齿均值更小。
但这也只是定性分析的结论,接下来用 response function 的曲线定量看结果。
scalable tcp 一次 probe 过程(一个锯齿)的时间(锯齿宽度)与 rtt 无关,只与 a,b 有关,求它:
W m i n ⋅ ( 1 + a ) t ⋅ ( 1 − b ) = W m i n W_{min}\cdot(1+a)^t\cdot(1-b)=W_{min} Wmin⋅(1+a)t⋅(1−b)=Wmin
解得:
t = − ln ( 1 − b ) ln ( 1 + a ) t=-\dfrac{\ln(1-b)}{\ln(1+a)} t=−ln(1+a)ln(1−b)
接着求丢包率,按积分法,一个锯齿连同其下面的矩形的面积等于一个 probe 过程发送的数据量,该过程中丢 1 个报文,可用一个锯齿定义丢包率 p,用 Wmax 指代 W(用均值 (Wmax + Wmin) / 2 更合适),即:
p = 1 t ⋅ ( 1 − b ) ⋅ W + 1 2 ⋅ t ⋅ b ⋅ W = − ln ( 1 + a ) ln ( 1 − b ) ⋅ ( 1 − b 2 ) ⋅ W p=\dfrac{1}{t\cdot (1-b)\cdot W+\dfrac{1}{2}\cdot t\cdot b\cdot W}=\dfrac{-\ln(1+a)}{\ln(1-b)\cdot(1-\dfrac{b}{2})\cdot W} p=t⋅(1−b)⋅W+21⋅t⋅b⋅W1=ln(1−b)⋅(1−2b)⋅W−ln(1+a)
p 与 W 在式子里可对换,如果嫌这个式子太复杂,可化简它。按照泰勒展开:
W = − ( a − a 2 2 + a 3 3 − . . . ) ( − b − b 2 2 + . . . ) ⋅ ( 1 − b 2 ) ⋅ p ≈ a b ⋅ p = 0.08 ⋅ p W=\dfrac{-(a-\dfrac{a^2}{2}+\dfrac{a^3}{3}-...)}{(-b-\dfrac{b^2}{2}+...)\cdot(1-\dfrac{b}{2})\cdot p}\approx\dfrac{a}{b\cdot p}=0.08\cdot p W=(−b−2b2+...)⋅(1−2b)⋅p−(a−2a2+3a3−...)≈b⋅pa=0.08⋅p
最后约等于的理由是 a 为 0.01,b 为 0.125,都很小。
同理,做出 reno tcp 的 W§ 表达式。依然按照面积的倒数求 p:
p = 1 ( 1 2 ⋅ W ) 2 + 1 2 ⋅ ( 1 2 ⋅ W ) 2 = 8 3 ⋅ W 2 p=\dfrac{1}{(\dfrac{1}{2}\cdot W)^2+\dfrac{1}{2}\cdot (\dfrac{1}{2}\cdot W)^2}=\dfrac{8}{3\cdot W^2} p=(21⋅W)2+21⋅(21⋅W)21=3⋅W28
因此:
W = ( 8 3 p ) W=\sqrt (\dfrac{8}{3p}) W=(3p8)
在对数坐标系中分别画出 scalable tcp 和 reno tcp 的 W 关于 p 的图像,scalable 的原因就一目了然了:
如前文,p 是管道最大容量(锯齿面积的倒数)的度量,reno tcp 和 scalable tcp 是两种度量方法,显然后者在双对数坐标系中更加线性可扩展,这是因为斜率越接近 -1 扩展性越均衡,作为极端反例,如果斜率为 0,将会是水平线,扩展性为 0。
可见,reno tcp 过于躺平,相同的 p,在高 bdp 时表现不佳,而 scalable tcp 比较斜但不至于过陡,在高 bdp 表现良好,但在小 bdp 表现一般,稍微差于 reno tcp。
注意 scalable 和 reno 的 response 曲线的交点,常见的手段是,当 cwnd 大于该交点所指示纵坐标时,使用 scalable tcp,其它情况使用 reno tcp,但这显然不是本质,反而容易弄巧成拙。
浙江温州皮鞋湿,下雨进水不会胖。