演讲人 赵家兴(组长)
大家好,我们“月卡”组做的项目是在数据流架构的智能网卡上硬件卸载eBPF程序,我是月卡组组长兼月卡行业创始人,同时和我一起卖月卡的还有陈昂,陶柯宇,付佳伟和李喆昊。(幻灯片切换)
大家电脑上的网卡应该都是1Gbps带宽的,这意味着什么(动画),意味着你的网卡,NIC,一秒钟最多可以接收128M的数据。(动画)现在这个数据撞到了你的网卡上,(动画)你的网卡当然要把这些数据先存进内存里备用,理想情况下你存入的速度就是128M每秒,当然这也比较容易实现,毕竟现在内存都很快。(动画)然后你的网卡会申请硬件中断,通知CPU现在有数据到了。(动画)然后CPU会调用网卡驱动,来处理你这个中断请求,同时网卡会禁用硬件中断,这样网卡可以不断地写入数据而CPU不受影响。(动画)然后驱动就会开始读取内存中的网络数据,理想情况下也是128M每秒,然后将数据交给上层的操作系统内核。(幻灯片切换)
内核部分的数据传输其实是很复杂的,比如Linux就涉及到多层函数、接口,还要经过多层的复制、打包和格式转换,经过一长串之后才能把数据包交给CPU来处理。比如说你并不需要这个数据然后要丢掉它,但是它居然过了这么久才真正进行了这样一个简单的操作。所以一般来讲,就算你接收网络数据和内存读写可以打满128M每秒,但是处理速度远远没有这么大,完整一个流程起码要损失几倍的效率。
所以有人提出了hook,钩子这样的操作,它会在你的整个数据通路的某一个部分提前拿钩子钩上一个程序,这个程序可以在数据经过这里时提前把处理操作做完,也就是我们少了一大段数据传输路径。直观上来讲你的钩子约低——越靠近网卡本身,你跳过的数据通路就越多,处理速度就会越高,越接近128M/s的极限。
所以在1Gbps下这样大概就能提高好多效率了,大家平时上网的时候基本下载也都很快,慢了也会是网速的问题不是你电脑的问题。
(幻灯片切换)但是问题其实是没有从根本上解决的,如果我让你的带宽加上三个零——128G/s。这是什么概念?如果你的内存真的以128G每秒来读入数据,你一定要保证CPU能跟上你的速度,快速处理完你的数据,不然这些数据就会等在内存里,不断地占用空间。就算你从数据读进来到CPU处理完它只有1秒的延迟,你的内存也是扛不住的——更何况刚才我们看的那么长的数据通路,大家用电脑的时候也没有这么快。
(幻灯片切换)问题的关键在哪?在于CPU的处理速度。冯诺依曼架构大家都清楚,那么它有哪些核心的缺陷?(动画)第一,数据传输效率远小于CPU计算效率;网络对冯诺依曼来说属于输入输出设备,是比内存还要低一级的,从网卡到CPU这么长的路径会影响你的速度。(动画)第二,PC在架构上限制了高并行性。PC,是控制流的概念,PC控制了你下一步执行哪个指令,可以说就是指令顺序执行——和并行是正好相反的。网络包一定程度上,不同的一些包之间是彼此独立的,如果我们能并行处理许许多多的独立的包那肯定是最好的,而且不会出现互相的上下文影响。确实,这些架构上的瓶颈是有所缓解的,比如我们引入了多级缓存,又引入了流水线、分支预测、超标量和乱序这种来提高并行性。(动画)那我们这就够了么,真的要用CPU来处理网络包,用许多核心,许多流水线和超标量CPU,来达到我们所需要的并行效率吗?128G每秒如此庞大的数据流量真的要让CPU来负担吗?
(幻灯片切换)真正能用到1Tbps这么大带宽的,基本上都是像亚马逊这种数据中心、云计算提供商等等。它们花了大价钱,买行业里最先进的CPU,在上面运行最领先的机器学习,管理者11万大规模存储,还有各种用户上百万的云应用和配套与虚拟机和容器——它们不会让这么贵的CPU去仅仅简简单单地处理网络数据。(动画)一个事实是,现在的数据中心有76%的工作负载来自网络。如果我们再让CPU负担网络处理,比如我们想一下会消耗多少内存、cache和流水线资源,这些资源本来可以用来运行多少云程序?
(幻灯片切换)所以这些企业终究要切换思路。那么我们想,大家买电脑现在都会看什么?你会仅仅看CPU的型号么?你要打游戏,你一定会看GPU(动画)。GPU是图形加速硬件,它不像CPU可以干一切可计算的东西,它是专门为图形处理来设计的,它的硬件上专门加速了图形处理的一些东西,所以它做图形处理比CPU要强得多。(动画)现在巴黎圣母院被烧没了,然后育碧说我们刺客信条大革命一周内免费,于是你从土豆服务器上好不容易下载下来却发现,你要有1070的显卡才能看清巴黎圣母院的细节。(动画)所以说我们有了硬件卸载的概念(动画),我们原本是在CPU上用软件来实现诸如网络包处理,图形处理的,现在我们引入一个专业的硬件,让硬件来负担这个工作。
(幻灯片切换)现在我们想,我们有什么硬件是专门为网络处理而生的呢。我们引入数据流处理器(NFP)(动画),他是“数据流”驱动的,不同于冯诺依曼架构是控制流PC驱动的。数据流驱动,就是只要你的数据准备好了,我的指令就立刻开始执行,然后执行结果也是数据,数据会流向另一个指令那里让它做执行。所以数据流驱动的指令是依赖于彼此的数据关系的,想想看,它可以最大程度上让你的指令并行,没有控制PC的限制。这正好符合我们网络数据处理彼此高并发的需求。图上就是我们要用的NFP架构,里面有60个核心,每个核心支持8个线程——我们可以同时处理480个网络包,这是哪个CPU自己都不可能做到的。然后我们想,网络数据的通路太长,太慢,我们要尽早处理,那么最早能摸到数据包的就是网卡了。所以,我们把NFP放到网卡上,就有了智能网卡,(动画)让智能网卡直接把网络包处理好。同时智能网卡是优化了数据传输的,并且减少一些输入输出操作,可以尽最大可能避免冯诺依曼里访存过慢的另一个问题。所以说智能网卡是专门为我们的需求所定制的。
(幻灯片切换)那智能网卡有多好,我们来看一下,(动画)网络处理第一个是速度,智能网卡的速度是单核CPU的12倍;第二个就是延迟(动画),因为你要降低延迟避免过多的占用内存和缓存。硬件卸载是延迟最低的,而且很平稳,因为网卡专门来做这个事情;而在CPU上就延迟更高且不稳定,因为涉及到CPU上还有其他应用会影响你的效率——涉及到调度。
(幻灯片)最后呢,智能网卡另一个很关键的特性是它可以编程。我们小组的工作呢,是用eBPF来编程智能网卡。(动画)eBPF是专为包处理设计的,一种虚拟CPU的架构,并且有概念上的多种存储结构和函数。同时eBPF也是一种指令集,它本身有自己的字节码,这意味着(动画)我们可以通过适当的工具链,从高级语言来编程——这节省了我们的工作。事实上,从C语言编写到编程到网卡上的整条工具链,都是被Linux和智能网卡本身支持的,所以说我们可以省下功夫来,只要专注于优化我们的程序本身,让程序更短更快,更能并行,来提高我们的包处理速度。这就是我们的工作,针对不同的网络数据处理需求来编程不同的eBPF,针对性的优化他们,希望能获得纳秒级别的延迟,并且打满网络带宽的速度。