令人无限遐想的各种PCIe加速板卡

时间:2022-06-25 12:15:04

声明

本文不涉及不论什么特定API,也不针对不论什么特定的厂商,可是仍然值得透露一点的是,某些加速板卡厂商的成功点和失败点恰恰都是在于其通用性,在这个人们依旧依赖专业板卡的时代,依旧将板卡视为解决专业化问题的时代,代理这些板卡并声称其能解决通用问题的厂商要谨慎!尽管,我非常看好通用化的板卡,可是我不是专家,即便我是专家,大家不是也总是攻击专家么?总之,矛盾的解决须要自己的推断力。

開始

如今出现了各种各样的PCIe加速板卡,这些板卡往往专注于处理一件事,从而释放CPU的越来越重的压力,当这样的往通用计算机主板上插卡以实现某种处理加速的办法成为趋势的时候,SDN就很多其它变成一种纯粹的概念了。CTMD,这些概念老子都TMD知道,关键是怎样用起来。
       有一家代理商来到了公司,说他们的板卡多么猛,让我有了一点兴趣!其实我一直以来都希望有一款能用硬件处理数据包路由查找,包过滤的板卡或者设备,可是一直都没有如愿,我之所以好奇是由于我想明确Cisco是怎么做的,我想明确这些板卡是怎么设计的,无非就是一些门电路,怎么能组合成如此复杂的硬件算法呢?!其实,门电路并不复杂,它全然遵循了UNIX的思想,或者说UNIX遵循了它的思想!当一系列门电路组合在一起的时候,就能够实现不论什么你想实现的东西,能够看下加法器的实现,比較简单。
       在我的正文之前,我不得不说的就是社会化生产,时至今日,无论再简单的东西,我们靠个人都无法完毕,我假设要想油炸一个狮子头,我必须浪费掉一锅油,我觉得这个事情不值得,所以我选择买。这就会社会分工,各行其是,各司其职!我和厨师之间的接口就是货币,我把钱给他,他把狮子头给我(货币真是个好东西,替代了物物交换,使不论什么价值的随意交换成为了可能),当然我没有考虑饭店老板,忽略了他们是由于我看不起他们。MD,我如今发现我连闺女的一个小玩具桶都做不好了,要想当年,我爸可是给我做了一个玩具桶啊...我爸还做了一个盒子,精致至极,如今还留着,尽管不是奢侈品,可是我觉得他那个年代的人,从木工,到定型,都是他一个人做的,我非常崇拜!可是如今不行了,假设你想要做出一个哪怕再简单只是的东西,你都须要一套完整的设备...完整的设备对于个人来讲负担太大了,就是说,社会化生长时期,一切都要靠分工。这不正是UNIX的思想么?
       做且仅做好一件事,这是一个伟大的思想。它造就了一种可能,即通过一个交换媒介,能够将简单的小元素组合出随意复杂的东西,这个交换媒介就是设计。RISC处理器是一个微观上的代表,而超多核心架构则是一个宏观上的代表,控制面和数据面的分离则是还有一个代表。

OS内核软件架构开销

单核心时代在内核实现协议栈不会暴露什么问题,无论是用户态程序还是内核代码,都共享一个运行流,假设频繁切换反而会带来切换本身的开销,因此内核往往代理很多事务。可是到了多核时代,内核就应该尽可能地放权,仅仅作为一个管理员存在,很多其它的事务交给用户态。用户态能够*且方便地将不同的任务绑定到不同的核心,让这些核心专注且发疯地干活,不再受到内核事务的干预,比方随意的中断导致的内核抢占、线程切换、处理器之间进程迁移,定时器等内核任务带来的开销。

多核心时代的OS内核

有一段时间,我是多么地赞赏Linux内核的进程在处理器核心间的负载均衡机制,多么赞赏诸多的所谓启示式智能化进程调度机制,可是如今,我走向了相反的方向,其实,那些机制确实非常智能,比方给睡眠太久的进程多一些运行的机会,比方依照历史权值平滑地进行进程迁移,等等这些。实际上引入这样的智能正是由于内核觉得用户态进程不会也没有能力在多核心架构这样的舞台上进行完美的表演,重新,内核代理了这些本应该由用户态进程自己负责的事务。其实,一直以来,内核始终保留了一个接口,该接口能够禁止掉内核对用户态进程的种种干预,比方你能够将进程强行绑定在一个核心上。
       依照UNIX最初的思想,内核就是一个控制面,数据面由用户态构成。可是处理器的架构让这个思想成了幻想。
       最初,系统仅仅有一个处理器核心,不得不设计出分时系统以便多个任务包含操作系统内核本身能够共享一个运行流。这样的内核和应用程序对等化的扩展改变了人们的思想,从而差点儿全部的通用操作系统都继承了这个思想。那就是不再刻意区分什么数据面和控制面,人们的视线转移到了哪里呢?操作系统的核心任务转移到了怎样提高分时系统的效率的同一时候在全部进程包含内核本身之间做到(加权)公平调度,而这些,用户态根本不用管。终于,被惯坏了的用户空间导致内核中一系列的智能算法出现,其实,这些算法的根据都是内核基于能获取的不多的进程状态推測的,内核永远也不会知道进程的本意究竟是什么。这就导致了一些误解出现的可能,比方内核文档说开启一个选项会提高性能,结果反而令人尴尬地降低了性能...
       本小节的标题是“多核心时代的OS内核”,可是到此为止我都还没有提到这个新时代的OS内核究竟应该是什么样子的,可是借古看今知未来,我想理解了上面那段历史以及其带来的悲哀后,新时代的OS内核是什么样子应该有一个大致的轮廓了。
       首先,内核没有必要和用户程序共处一个分时系统了,当然假设你愿意,你依旧能够让它们共处。实际上虚拟化就是这方面的体现,一个多核心系统上跑多个OS内核...对于核心的利用,内核要给用户态很多其它的控制权。我们思考一下计算机编程的本质,就是对CPU的编程,让它运行我们的程序,而不是针对OS内核提供的系统调用接口的编程。此时,OS内核须要做得仅仅就是处理好共享资源的管理和分配就可以,当时间在多核心下已经不再是共享资源的时候,它就应该放弃这部分的管理权,除非当一个核心上存在多个进程共处一个分时系统的时候,或者说有进程主动要求的时候,它才须要介入。这就提供了一个可能,在某一个核心或者某几个核心上取消分时,专注于一个工作。这也预示了一个趋势,那就是超多核系统架构,依照逻辑分配处理器核心,而不是依照进程来分配处理器核心。前后接力,这就可能全然避免切换以及切换导致的一系列开销。

硬件架构的开销

传统意义上,非片上完毕的操作总是须要一条将全部一切连接起来的总线,往往这条总线就是瓶颈!Intel的架构使这一风格变的流行,以前有人在比拼自己的电脑的性能时,前端总线的带宽是一个硬性指标,后来AMD在兼容IA32的前提下改变了这个事实,可是还是不彻底。假设使用片上存储器将会解决这一问题,可是受限于工艺技术以及冷却因素,片上存储器一般都不会非常大,可是即便是不使用片上存储器也还是有办法的,那就是改变处理器核心和存储器之间的连接方式,使用矩阵的连接方式替换总线方式。实际上,极端点说,多核心时代,总线的存在就是一个错误。换句话说,总线是单核心时代的遗物。
       PCIe总线似乎开了一个好头,软化了硬总线,将总线拓扑其实变成了基于HUB的星型拓扑,反复了以太网的进化模式,或许仅仅有当初的交换式以太网能够与其媲美。可是,PCIe本质上还是为了互联外围设备的,并不适合处理器和内存之间的连接,可是它的思想却是能够借鉴的。那就是改变拓扑,从而,全互联拓扑,矩阵拓扑代等交换结构替了总线拓扑。仅仅要总线变成交换式的,那么“总线”也就成了一个名称,像CSMA/CD变成文物一样,昔日的前端总线上跑的各种协议也将不复存在。

新架构上的协议栈

协议栈属于数据面,因此正确的做法就是用户态的协议栈,利用多核心分发运行流,比方一组核心专门处理链路层转发,一组核心专门负责ACL匹配,一组核心专门负责包分类...全然没有切换,这使全部的cache都是新奇可用的,矩阵连接方式使每个核心都能快速訪问到不同的内存区域,降低了总线竞争和*等待。
       网络数据被网卡接收以后,应该放到用户态的一个buffer,假设你觉得这不是和内核没有关系了吗?不!网卡是靠驱动接收数据的,而驱动是OS内核直接管理的,也就是说,从网卡芯片接收的动作是发生在内核态的,仅仅是内核随即就把这个数据包放到了用户态,并没有在内核协议栈处理它。相似的思想也被用在了磁盘操作的Direct IO中,即内核不再保留缓冲,全然由用户态自己负责。

关于协处理器

我本人是不看好协处理器的,由于它是对通用计算的一种反叛,部分或者彻底抵消了编程带来的方便性灵活性以及经济利益,比方最開始的ASIC转发芯片,将指令全然固化在硬件,后来的协处理器添加�了灵活性,使之变成可编程的,可是能完毕的功能毕竟有限,只是正如你所示,事情正在一步步走向通用化。上世纪的CPU+编程代替了各种专用设备,当这样的架构变成瓶颈的时候,专用设备又出现了,比方上面提到的ASIC,各种加密卡,协处理器之类,然而由于GPU和各种超多核心处理器的实现,更高层次的向通用化的统一进程正在进行中。
       眼下的路由卡上所谓的智能芯片其实就非常专业化,也就是说它并没有通用处理能力,典型的路由芯片用普通的比較器,移位寄存器,选择器,复用器就能够完毕,仅仅要懂点计算机组成原理的能够说都能够设计出一个简单,假设你想看下其软件原理,那就看下Linux的TRIE路由查找算法的实现,或者看一下BSD的路由查找算法,它们都比纯硬件实现复杂了不少,可是基本思想却是一致的。假设想提高性能,能够採用并行的CAM匹配。尽管大大加快了路由查找效率,可是随着通用处理器架构越来越扁平化(低主频,低功耗,多核心),我想专用芯片的神话快要被打破了吧。

新架构和传统架构的交互

新的超多核心架构眼下很多其它是以板卡的形式存在,很多其它地採用PCIe的方式插在传统架构设备的主板PCIe槽中,造成这样的局面的原因除了传统主板的既有投资等经济因素之外,另外的原因在于大多数的这些新架构板卡都带有一定的专用性,比方GPU,Intel千兆/万兆卡,cavium加密卡,Tilera Gx处理卡,我个人对GPU和最后一个Tilera处理卡比較看好。
       假设以板卡的形式存在,受既有投资和传统思维的影响,主程序还是跑在老架构上,这就不可避免地要和主设备进行交互, 我觉得,这样的办法是极其不妥的,传统大而全的帝国式OS内核,传统拥堵不堪的主板总线,传统单核思想下设计的应用程序都将成为瓶颈和累赘。为何不直接将程序扔在板卡上呢?假设这样,就涉及到板卡上的工作由谁充当控制面的问题,当然是由新架构时代的OS内核了。也就是说,板卡上跑着一个超级轻量级的OS内核,该内核最大限度的放权给用户态应用,不处理协议栈,仅仅提供共享资源的管理和调度。Tilera Gx处理卡提供了这样的方式。这样,PCIe就不再是数据面意义上的接口了,很多其它地充当了管理面的接口,这样管理面由老架构主机提供,控制面由板卡OS内核提供,数据面由板卡用户态提供,假设不须要管理,极端点说,PCIe全然就是一个供电接口。
       要澄清的一点是,非常多人使用加速板卡的目的是弥补主板处理器主频和功耗而带来的不足,他们的着眼点还是主板,而认识不到传统意义的主板上的系统仅仅是一个管理平面而已。他们的需求促使PCIe带宽不断的提升,终于PCIe也会吃不消的,总的来讲,大多数的人仅仅是将这些板卡用于加速而已,并没有将数据面让其完整接管的意思,这实际上是一个错误的思想。这个思想的本质是单一通路思想,人们自古以来就一直在拒绝无边界的东西,于是有了各种门和口,比方古代的城门,如今的绕城快速出口等,假设循着这个思想,这些门或者口随着流量的添加�早晚会成为瓶颈,于是打破这些门或者口才是正确的思想。干吗非要主板和板卡协作,直接全部交给板卡岂不更好?!

关于核心网络技术

其实,相似Cisco这类厂商在非常早的时候就已经採用这样的新架构的思想了,仅仅是说核心网络业务一般都比較单一,不外乎路由,交换,防火墙等,因此这样的模式也就没有被推广。仅仅是在进入后终端虚拟化时代之后,数据中心这样的资源子网的压力不断添加�,才迫使server已经採用或者将要採用分离了数据面,控制面,管理面的混合架构。假设在这样的分离的思想上更进一步,那就是SDN了,而SDN正是传统核心网络技术和云时代的数据中心技术共同催生的。SDN在平面分离思想之外,额外添�了在管理面上集中化的思想,就像一个线扎一样,它提供了一个统一的视图。每一种网络技术都有过这样的过程。
       本来并没有路,走的人多了也就有了路,这些路起初是无人管理的,可是终于却有了人集中管理,路网时至今日都是这么发展的,无论是古罗马的道路网还是中国的铁路网。电话网何尝不是这样,假设你看到19世纪末的电线杆,你会发现它们是多么得乱,可是如今你还觉得乱吗?能够说,整个人类文明就是一个结网的过程,该过程中不断反复着分布和集中,融合和分离,而主角就是,数据面,控制面,管理面。
       最后说说SDN,它并非想象的那么简单,可能须要一点颠覆性的思维才干更好的理解。要记住的是,如今的网络都是分布式控制的,这是一个正常的技术演化过程导致的必定结果,也是历史发展的必定。整体来讲,这是分层协议模型的必定,在这个模型中,网络分为承载网和叠加网,即叠加网作为承载网的载荷运行,不论什么一层都能够做承载网,不论什么一个层都能够做叠加网,比方X over Y,分为下面三种模式:
1.典型的依照协议栈顺序封装的,如UDP over IP,HTTP over TCP,IP over Ether;
2.常见到不典型的上层封装下层的,如PPPoE,IPoATM...OpenVPN本质上也是基于这个模型的,它属于IP/Ether over UDP/TCP;
3.随意两层之间添�新层的,如IPsec的ESP/AH,SSL/TLS。
可是SDN打破了全部这一切。SDN的世界,数据全然依照流表的建议转发,而流表的建立全然和数据的转发分离,换句话说,即使没有分层协议栈,仅仅须要告诉一个数据包该从设备的哪个port发送出去,就能完毕数据包的路由,也就是说,协议栈的处理大大降低了层层解析包头协议头的工作量,仅仅是匹配流表就能够了,就算你自定义一个非TCP/IP的协议,仅仅要能建立流表,就能将其转发!而流表的建立,根本和详细协议无关,它是一套独立的协议!因此,想当然的,极端一点,你能够将分层协议彻底转移到控制面,而在数据面全然抛弃分层协议...

总结

看看新架构板卡所呈现的,看看现实中我们遇到的。因此,SDN并非什么新的思想,而是一个古老的思想,从UNIX出生的年代開始,我们绕了一圈,终于又回到了UNIX的思想。