用流水线提高转发吞吐

流水线不会缩短延时,但能提高吞吐。

长程逻辑是转发吞吐劣化的罪魁祸首:
在这里插入图片描述
优化方案有两种:
在这里插入图片描述
多CPU涉及保序处理,比较复杂,一般不采用,如善用的RSS均不会对单流进行并行处理,因此一般将长程分割成多个短程,流水线接力。

各软件转发产品的实现不谈,仅谈wireguard,抛砖引玉。

wireguard采用的是第二种方式:
在这里插入图片描述
这就是单流吞吐比Open虚拟专网好的原因,路线是对的,但wireguard-go未竟全功。

我觉得loop1和loop2还是太长了,紧接着TUN的loop应该只做一件事:

  • 将TUN读出的packet放入buffer,或将buffer作为packet写入TUN。

紧接着socket的loop应该只做一件事:

  • 将socket读出的数据放入buffer,或从buffer取出一部分写入socket。

剩下的就是保序和加解密处理了,这些可以充分调用以及利用所有CPU,将核心处理池化(实际上就是分离了保序和处理,说到底还是要处理标量,摆脱保序带来的约束),最终将吞吐最大化:
在这里插入图片描述
我也没改啥,只是将很多逻辑移到了原本仅做加密解密的goroutine里,单流吞吐就从800Mbps提升到了1.2Gbps。

寻求质变,架构永远比实现细节重要。epoll的C实现,golang实现,rust实现,不会带来质的差异,愈发差异而已,若是语言带来大不同,定有人早就发现并解决。

当然,我忽略了很多异常处理,所以这个修改仅仅属于测验。

对于wireguard-go,横向扩展没什么技术含量,正如我当年将Open虚拟专网改成多线程一样,这种修改远不如启多个实例,多实例既简单又稳定,只是让人看起来没有工作量罢了。当然,如果你非要修改代码,总有1万种理由,我是过来人,岂能不知,现在回想,甚为惭愧。

提高单流吞吐才更重要,比方说拆流水线。想当年,汽车也是通过这才能批量下线的,从奢侈品变成了大众商品,说到底还是吞吐高了。

说说TCP。

端到端的TCP传输亦可通过流水线提高吞吐,这就是中继的意义所在。SDWAN在长程传输才有意义,而长程传输的延时尺度下,你用内核协议栈实现,你用DPDK实现,你用rust实现,都将不是重点。重点在你如何拆流水线,以及如何处理好每一段。

闲着没事,移动几行代码,把wireguard-go的几行代码移动到加解密goroutine里,竟然带来了惊人的质变,从800M到1.2G,至于从1.2G到1.22G,我就不行了,只能pending。皮鞋胖,写作诗。

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值