自动驾驶场景下TCP协议参数优化调整案例分享
RTT
往返时间,从tcp协议栈决定发包,到收到回包的时间。
包含本地驱动,网卡硬件,网线,交换机,收包方处理的耗时。需注意如果开了delayed ack,协议栈未做特殊处理(默认没做),则RTT可能包含delayed ack时间。
delay ack
理论上来说有可能会延迟40ms发ack;实际对我们来说概率非常小,详见delayed ack代码和实车环境影响分析
cwnd 40
拥塞窗口。in flights数据包的数量不能大于cwnd。linux是按照包数而不是数据字节来管理的。
当开启gso后,会根据skb→size / mss来计算发出的包量;4.9的内核收到ack时也会按照确认的包数量扩大拥塞窗口(老内核不是)。
所以gso不影响拥塞窗口计算。
initcwnd 30
初始拥塞窗口。当连接刚建立,或者重置拥塞窗口时,使用这个值。
RTO 4ms
如果发出的数据包,未得到回复,会在rto时间之后进行重传。
在丢包场景下,rto就是丢包带来的额外延迟。
linux内核代码写死了全局rto_min=200ms,可以通过路由表ip route change ..... rto_min 10ms覆盖全局的rto_min
rto需要跟quickack联动,默认delayed ack可能40ms才回ack包,rto_min
快速重传
当收到3个“错误”的ack时,对未确认数据包进行重传。
涉及的扩展算法较多,对我们影响不大,不展开。
TLP 4ms
当发包端最后一个数据包丢包时,响应ack达不到三个,无法触发快速重传。
此时会把最后一个包重传一下,触发对端响应。
但在linux内核实现时,TLP和RTO共用了一个定时器;
判断1: tlp时间 = max(..., 200ms),这200ms是写死的,除了改内核代码外无法修改
接着判断2: tlp时间 = min( tlp时间, rto时间)
因为rto_min可以被路由表覆盖,实际上在我们修改rto_min后,tlp时间等于rto时间
从结果上来看,非常的蛋疼。因为在局域网情况下,TLP时间总是小于RTO时间,导致未能起到尽快触发重传的效果,反而还抢了RTO的定时器
TODO 实验记录单独记录文档,引用到这里
下图中 8253 就是一个 TLP 包,因为 50362853 + 12567 - 983 = 50374437。12ms 后重传了尾包
cubic
linux默认使用的拥塞控制算法。windows多个版本也是使用此算法。
启动时使用initcwnd,每个rtt窗口倍增,达到ssthresh后线性增长。
发生丢包时cwnd=1,同时调整ssthresh。丢包的cwnd=1是在tcp协议栈写死的,不受拥塞控制算法影响,见tcp_enter_lost函数。
bbr
google做的拥塞控制算法,bbr比传统拥塞策略要先进很多,主要体现在:
1 摒弃了用丢包触发限速的策略,会通过延迟的变动来调整对网络情况的探测;
2 除了in flights包数量控制外,还会控制发包的频率间隔。
但是bbr的很多设计细节不适合自动驾驶领域。
例如对rtt 出流量时,缓冲区开始积压,积压超过buffer size时就会丢包。
根据我们的实验可以证明这一点:
TODO 这里单抽一个文档,贴代码,测试环境,详细记录,引用到这里
udp发包实验测网卡缓冲区大小:
1400字节,10us一个包,延迟增加1800us左右开始丢包。即180个包,250KB积压开始丢包。
700字节,设10us一个包,实际7.7ms左右一个包,延迟增加3000us左右开始丢包(不稳定,可能是发包速率就不稳定)。即390个包,273KB积压开始丢包。
14000字节,100us一个包,延迟增加1800us左右开始丢包。即18个包,250KB积压开始丢包。
根据实车观察,一旦触发丢包,会在几毫秒内有很大的丢包率。
现象1:dup ack很少,远少于rto/tlp超时触发的次数。
现象2: rto/tlp触发时,一般都是连续一段数据都需要重传。
这个现象符合理论分析。当入流量>出流量时,缓冲区增加,当缓冲区满时丢包。
一旦触发丢包,入流量无改善的情况下,会有相当高的丢包率。
带宽 ,RTT,窗口
带宽/ms = 窗口 * 每ms包数量 = 窗口 ÷ RTT
以xavier的1Gb/s网络计算:
每个数据包的发送速度 = 1.5KB ÷ 1Gb/s = 0.012ms
打满1Gb/s带宽,需要每秒传输83个1.5KB的数据包 => 打满1Gb/s带宽,窗口 >= 83 * rtt
以switch 128KB buffer计算:
积压85个包会打满缓冲区,85 * 0.012ms = 1ms,即当入流量大于出流量时,缓存积压的包会增加,由此会导致rtt上升。
这也是bbr基于rtt变化调整发送速率的理论基础。
使用ss -i -t实车观察rtt:
在网络良好且空闲时一般在0.25ms左右;
在流量上升时,一般在0.5-1ms(缓存积压+收包端CPU0繁忙导致耗时增加);
如果持续超过1.6ms,一般丢包就比较严重了。
因为是手动采集了100多次数据做的观察,具体数值不够准确,但大致趋势应该是没错的。
实验:rtt,带宽随cwnd变化
不锁的情况,speed [829.35 Mb/s],rtt:1.467/0.181,cwnd:149
锁40的情况,见抓包no_drop,speed [781.53 Mb/s],rtt:0.408/0.08,cwnd:40
锁30的情况,speed [707.76 Mb/s],rtt:0.314/0.057,cwnd:30
锁20的情况,speed [590.34 Mb/s],rtt:0.293/0.059,cwnd:20
自动驾驶的场景特征
1 自动驾驶中大多数流量,是定频发生的。
2 不同流量(topic)有不同的优先级(DAG优先级)。
3 硬件环境是已知的,如6*xavier的网络拓扑,2*orin的网络拓扑。当实际探测到的硬件环境与设计不符时,应报故障并做降级处理。
丢包场景分两种:
场景1 MAP在中间件中的多个topic流量同时触发。此场景的特点是持续时间短,一般

