OVS+DPDK Datapath 包分类技术

本文主体内容译于[DPDK社区文档],但并没有逐字翻译,在原文的基础上进行了一些调整,增加了对TSS分类器的详细阐述。

 

1. 概览

本文描述了OVS+DPDK中的包分类器(datapath classifier -- aka dpcls)的设计与实现思路。本文的内容主要牵涉到分类器对封包流的分类及缓存技术,并且对于一些典型场景下的细节给予解释说明。

虚拟交换机与传统硬件交换机的差别较大。硬件交换机通常都使用TCAM以求高效率的包分类与转发。而虚拟交换机由于自身是纯软件实现,不能依靠特殊的硬件设计,为了达到较高的工作效率,在设计和实现上大量使用缓存技术。OVS是一个兼容OpenFlow协议的虚拟交换机软件,发展比较迅速,基本上算是当前的业界网络虚拟化中的标杆与事实标准,OVS为了获得较高的转发性能,采用的基本思想也比较朴素:缓存。

OVS的数据转发面(datapath -- aka dp)有多种实现,其中比较著名的有基于Linux内核协议栈的实现与DPDK的实现。当采用DPDK的实现时,封包的处理流程将完全绕过内核协议栈。OVS+DPDK在封包的查找匹配中,共有三级查找表/缓存的设计。最底一级是为完全精确匹配(Exact Match Cache -- aka EMC),如其名所示,这一级的查找匹配无法实现范围匹配、掩码前缀匹配等功能。中间一级就是本文的主角:dpcls,这一级的包分类器其实就是[这篇论文]描述的TSS分类器,使用论文中描述的TSS算法,这一级的分类器可以实现范围匹配、掩码前缀匹配等功能。如果单纯的作为一个虚拟交换机,仅有最底一级与中间级已经足够,而为了兼容OpenFlow协议,OVS还有最上一级的查找表:OpenFlow分类表(ofproto classifier table),其表项由OpenFlow控制器管理。下图基本展示了这三级查找表/缓存的设计逻辑。

 

 

当一个包到达时,优先查找最底一级的EMC表,命中则转发,不命中则继续查找中间一级的包分类器,再不命中的话锅就扔给OpenFlow的分类器了,再不命中就要扔给OpenFlow控制器了,逻辑很清晰。

当封包流很稳定,流的数量EMC表也能hold住的时候,转发的性能取决于EMC表的查找匹配效率。这算是理想状态,现实世界很残酷,EMC表的容量有限,在封包流的数量达到一定规模的时候,决定转发效率的瓶颈就变成了中间一级的dpcls。所以dpcls本身的处理效率对于OVS+DPDK来说是很重要的一个关隘,其设计与实现是比较精巧的。

 

2. TSS分类算法简述

2.1. rule的定义

这里简单的介绍一下TSS分类器所使用的分类算法,不牵涉任何优化手段,仅介绍原算法本身。

定义rule就是单条的包过滤规则+动作,它可能长这样:

1 Rule #1: ip_src=10.10.2.0/24 ip_dst=* protocol=UDP port_src=* port_dst=4789 actions=drop
2 Rule #2: ip_src=10.11.0.0/16 ip_dst=* protocol=TCP port_src=* port_dst=23 actions=output:3 

为了描述清晰起见,rule中的过滤规则使用了稳定的五个字段,即经典的五元组,但实际上rule可以使用任意多的字段

rule中的过滤规则,或者叫匹配规则,是由多个单字段过滤规则组成的,这些过滤规则符合,或者能转化为以下的形式:

1 字段值/掩码前缀

比如,对于IP地址来说,经常就是如下的形式

1 ip_src=192.168.0.0/16
2 ip_dst=33.23.12.0/24

对于IP头中的协议字段来讲,由于协议字段仅占八位,多数情况下都是严格匹配,比如上面列出的两个rule,其协议字段都是严格匹配为UDP或TCP,故它们可以写成如下形式

1 protocol=6/8(TCP)
2 protoco=17/8(UDP)

对于四层头中的端口号,一般情况下在各种防火墙也好,OpenFlow流表也好,匹配规则一般都写成精确匹配或者取值范围的形式,精确匹配可以很简单的写成字段值/前缀掩码的形式,无非就是掩码是16位掩码,而取值范围要转化为字段值/前缀掩码的形式,就需要一定的转化。我们举个例子好了,取值范围[12345, 33123]可以转化为如下形式:

 1 0011 0000 0011 1001 | 12345
 2 0011 0000 0011 101* | 12346~12347
 3 0011 0000 0011 11** | 12348~12351
 4 0011 0000 01** **** | 12352~12415
 5 0011 0000 1*** **** | 12416~12543
 6 0011 0001 **** **** | 12544~12799
 7 0011 001* **** **** | 12800~13311
 8 0011 01** **** **** | 13312~14335
 9 0011 1*** **** **** | 14336~16383
10 01** **** **** **** | 16384~32767
11 1000 0000 **** **** | 32768~33023
12 1000 0001 00** **** | 33024~33087
13 1000 0001 010* **** | 33088~33119
14 1000 0001 0110 00** | 33120~33123
15 1000 0001 0110 0011 | 33123

上面这个例子可能过分了一点,但足以说明一个问题:取值范围在数学上是可以被转化为字段值/前缀掩码这种形式的。
至此,rule中的常见的三种过滤规则都可以转化为字段值/前缀掩码的形式

1 精确匹配   ==   值/全bit掩码
2 掩码匹配   ==   值/掩码
3 取值范围   ==   可以转化为多个 值/掩码 的组合
4 任意值     ==   掩码位为0

将$字段值$记为field,将前缀掩码记为mask,则单个匹配规则的记法如下:

则一个rule的定义与记法就如下:

注意组成单条rule的多个匹配规则之间的逻辑关系是与/且,所以当匹配规则中有取值范围时,一个rule要按上面的记法,就得拆分成多个rule

2.2. tuple的定义

按照上方的定义,我们可以写出几个rule,如下所示:

1 Rule #1: ip_src=192.168.0.0/16
2 Rule #2: ip_dst=23.23.233.0/24 protocol=6/8(TCP) port_dst=23/16
3 Rule #3: ip_dst=11.11.233.0/24 protocol=17/8(UDP) port_dst=4789/16
4 Rule #4: ip_src=10.10.0.0/16

在上面的例子中,我们省略了不关心的字段。
以上面的4个rule中,我们认为Rule #1与Rule #4属于同一个tuple,而Rule #2与Rule #3属于同一个tuple。
即属于同一个tuple中的所有rule有以下特点

1 使用相同的匹配字段
2 每个匹配字段都使用相同的掩码长度

假如我们将匹配字段仅限于传统的五元组,并且把不关心的字段也写出来,如下面这样:

1 Rule #1: ip_src=192.168.0.0/16 ip_dst=0/0 protocol=0/0 port_src=0/0 port_dst=0/0
2 Rule #2: ip_src=0/0 ip_dst=23.23.233.0/24 protocol=6/8(TCP) port_src=0/0 port_dst=23/16
3 Rule #3: ip_src=0/0 ip_dst=11.11.233.0/24 protocol=17/8(UDP) port_dst=0/0 port_dst=4789/16
4 Rule #4: ip_src=10.10.0.0/16 ip_dst=0/0 protocol=0/0 port_src=0/0 port_dst=0/0

可以明显看出,其实属于同一个tuple中的所有rule仅有一个特点:

1 匹配字段的掩码长度相同

即tuple的定义与记法如下:

 

2.3. 分类算法

分类算法要解决的问题,可以描述如下

1 有一大堆rule
2 收到一个包
3 找到与这个包最匹配的rule,如果有多个匹配,按一定策略找出最优的那个

我们将最后一步的这个动作称为match,即是匹配查找

这不是一人困难的问题,至少在算法角度来讲,要解决这个问题并不困难,困难的是怎样快速的解决这个问题。最朴素的做法是:用线性表把所有rule都串起来,每次match都是一次遍历操作,时间复杂度O(N)

 

显然朴素是不行的

2.4. TSS

TSS首先把所有的rule进行分类,分类的依据是同tuple的所有rule在一起。
其次对于同一个tuple下的所有rule,以哈希表的形式将这些rule存储起来。

依然用例子来说明,还是上方提到的四条rule,如下:

1 Rule #1: ip_src=192.168.0.0/16 ip_dst=0/0 protocol=0/0 port_src=0/0 port_dst=0/0
2 Rule #2: ip_src=0/0 ip_dst=23.23.233.0/24 protocol=6/8(TCP) port_src=0/0 port_dst=23/16
3 Rule #3: ip_src=0/0 ip_dst=11.11.233.0/24 protocol=17/8(UDP) port_src=0/0 port_dst=4789/16
4 Rule #4: ip_src=10.10.0.0/16 ip_dst=0/0 protocol=0/0 port_src=0/0 port_dst=0/0

它们将被分别两个tuple,我们分别记为tuple #1与tuple #2,这两个tuple的定义如下

1 Tuple #1: ip_src_mask=16 ip_dst_mask=0 protocol_mask=0 port_src_mask=0 port_dst_mask=0
2 Tuple #2: ip_src_mask=0 ip_dst_mask=24 protocol_mask=8 port_src_mask=0 port_dst_mask=16

每个tuple下都建一个哈希表,我们分别记为ht #1与ht #2。tuple下的rule就存储在相应的哈希表中,如下所示

HT #1: Rule #1 | Rule #4
HT #2: Rule #2 | Rule #3

上面只讲了哈希表中的value是一个个的rule,但没有说key是什么,下面以Tuple #2中的Rule #2为例说明一下:

首先用tuple的掩码去**与**rule中的各个**字段值**,丢弃tuple不关心的位,得到:

1 ip_src=_ ip_dst=23.23.233 protocol=6 port_src=_ port_dst=23

然后把这些位拼接起来,就是哈希表的key,在本例中,转换为二进制如下:

1 key = 0001 0111(23) 0001 0111(23) 1110 1001(233) 0000 0110(6) 0000 0000 0001 0111(23)

最后,用这个key去做散列,即是哈希表的索引

 

2.5. 匹配过程

现在所有的rule都被分成了多个tuple,并存储在相应tuple下的哈希表中

当要对一个包进行匹配时,将遍历这多个tuple下的哈希表,一个一个查过去,查出所有匹配成功的结果,然后按一定策略在匹配结果中选出最优的一个。

依然是举例说明,假设我们收到下面这样一个包:

1 Packet #1: ip_src=192.168.1.2 ip_dst=23.23.233.234 protocol=UDP port_src=4344 port_dst=4789

 

首先在第一个tuple中进行匹配查找

1) 将包的各个字段与tuple定义的mask进行**与**操作,得到

1 ip_src=192.168 ip_dst=_ protocol=_ port_src=_ port_dst=_

2) 将有效位拼接起来,得到key

1 key = 1100 0000(192) 1010 1000(168)

并且这个key去Tuple #1下的哈希表做查找,则会命中Rule #1

3) 匹配成功,结果为Rule #1

 

然后在第二个tuple中进行匹配查找,显然也会匹配成功,命中Rule #3

最终,假设我们采用最长匹配策略的话,最终的匹配结果应当是Rule #3,因为该rule所属于的tuple掩码位数比Rule #1多。

 

2.6. TSS vs. 决策树

决策树又称分类树,是一种十分常用的分类、查找、搜索手段。但在网络封包的分类工作中,它并不适合,理由如下:
* 决策树的插入与删除效率不高。虚拟网络环境中的包分类器中的分类规则并不稳定,对于OVS+DPDK来讲,将其视为OpenFlow交换机来使用的话,很多场景下都会导致中间一层的包分类器中的规则发生大量的插入与删除操作。
* TSS的时间与空间复杂度均为O(N)。在最坏情况下,每个tuple中的哈希表仅有一个条目,哈希表的数目将等同于rules的数目,查找效率将趋近于线性查找。这不算糟糕,比起决策树来说,还好上不少。
* TSS中可以使用任意数目的封包字段进行匹配,而决策树一旦成型,要增加或减少一个字段就比较麻烦。在所有的匹配规则都是以传统五元组(ip_dst+ip_src+protocol+port_dst+port_src)进行匹配的情况下,新插入一个使用了第六个字段的匹配规则,这种事情对于TSS分类器来说,没有任何额外的负担,但对于决策树来说,就需要调整整颗树。

在TSS分类器中,查找就意味着一个个的去查各个tuple下的哈希表,直至某个哈希表命中。所有哈希表中的表项都是不重复、不互相覆盖的,这个前置要求解决了TSS算法中的一个蛋疼点:有多个匹配结果时如何最长匹配,在这个前置要求的前提下,一旦查找命中,那么只可能是唯一命中。分类器中的多个哈希表的顺序是随机的,表和表项都是在工作的过程中动态创建的。

 

2.7. 小结

TSS分类算法的时间复杂度为O(M),其中M是tuple的数量,空间复杂度是O(N),其中N是共计的rule的数量,无论是时间复杂度还是空间复杂度都在一个比较好的范围里。并且相较于其它分类算法,对待rule的插入与删除更友好

TSS分类算法充分利用了网络封包字段值的一些统计学特性,比如以掩码前缀为过滤规则的rule在实际防火墙或者路由器中是十分常见的。

Open vSwitch的数据转发面在包分类上采用了该算法,OVS+kernel datapath中的包分类在细节上与DPDK datapath有比较大的出入,并且随着版本的更迭也在做一些调整,但两者其实都使用的是TSS算法,两者细节处的不同也仅限于如何优化算法的执行效率。关于OVS的总体设计决策,可以参见[这篇论文],论文没有提及任何实现细节,仅在宏观上阐述了OVS的设计决策。
kernel datapath在历代版本中尝试过为tuple/哈希表增加ranking权重、缓存skb_hash与tuple/哈希表等手段,以期望减少遍历多个tuple/哈希表时能尽快命中正确的tuple/哈希表。
DPDK datapath优化的思路则是在TSS分类器下层建立一个小规格的、更快速的完全匹配EMC缓存,以期望在大多数情况下不借助TSS分类器能正确转发大部分流量。

TSS算法,或者叫TSS分类器最初发表于[这篇论文],发表于1999年。

 

3. 对哈希表进行排序以优化dpcls

在OVS 2.5 LTS分支上,每个PMD线程都会创建一个TSS分类器实例。每次查找都是对分类器中哈希表的遍历,平均开销为N/2,这里的N指的是哈希表的数量。尽管这样理论上看起来很完美,但实际开销中,算散列值也是一部分比较大的开销:每查一个哈希表,都要根据tuple的定义重新掩一次匹配字段,重新算一次散列值。

为了一定程度上缓解这个问题,OVS在2.6版本中,为每个哈希表都增加了一个ranking值,这个ranking值以哈希表命中查找的次数为准,这很好理解,将热度高的哈希表提到前面来,热度低的哈希表放在后面,以尽量减少平均查找哈希表的次数。

除了上面的改进,在2.6版本中,不再是为每个PMD线程创建一个dpcls实例,而是为每个ovs-port创建一个dpcls实例。这个改进就是工程实践上的经验性改进了,由于同一个port收上来的包有很强的相似性,这样为每个port都创建一个dpcls实例,这样dpcls实例中的哈希表数量,即tuple的数量会变少,变相的也提高了查找效率。

下图展示了多个dpcls的逻辑:下图中有三个ovs-port,其中有两个ovs-port(DPDK_1与DPDK_2)背后是物理网络接口,另外一个ovs-port(VM_1)背后是vHost User型的虚拟port。每个dpcls实例将负责从对应ovs-port收上来的包的分类工作。比如,比VM_1接口收上来的包由线程PMD thread 1处理,该线程先进EMC对包进行匹配,匹配失败后该线程负责对包进行掩码处理,算散列值,然后以该散列值去VM_1 dpcls中去查找。

 

 

4. 模糊匹配(wildcard matching)的实现技术

这里阐述的是中间一级的TSS分类器如何使用哈希表实现上层OpenFlow表项指导的模糊匹配功能。
假设OVS OpenFlow流表中增加了一条流表,其匹配规则如下所示:

1 Rule #1: Src IP = "21.2.10.*"

这个规则可以通过如下的ovs命令添加进流表中:

1 ovs-ofctl add-flow br0 dl_type=0x0800,nw_src=21.2.10.1/24,actions=output:2

当OVS收到一个源IP字段值为21.2.10.5的包时,并假设EMC与dpcls都查找失败,这个包将送至ofproto classifier中进行匹配,并且会匹配至上面添加的这条规则。匹配成功之后,相应的学习机制会使得dpcls与EMC中都添加一个相应的表项。EMC中添加的表项是一个严格匹配表项,没有模糊匹配功能,而dpcls中添加的表项将带有模糊匹配,我们现在要阐述的就是dpcls如何添加这个表项。

下面的几个小节将一步一步的阐述OVS+DPDK如何建立起tuple哈希表,如何进行查找。我们假设在进行下面几个小节的操作之前,整个OVS+DPDK在中间层和下层,即dpcls与EMC这两层,是不存在任何条目、表项的。

4.1. 单ovs-port场景

上文中说过,在OVS 2.6版本之后,实际实现中是为每一个ovs-port创建一个独立的dpcls实例,下面的阐述中,将先介绍简单的场景,先介绍在单ovs-port场景,仅有一个dpcls实例的情况下,包分类是如何进行的,之后在单ovs-port场景的基础上再介绍实际实现中的多ovs-port场景,多dpcls实例下包分类是如何进行的

4.1.1添加第一个Rule

在向dpcls中的某个哈希表添加Rule #1之前,我们先要创建一个Mask #1。这个Mask如下

1 Mask #1: 0xFF.FF.FF.00

Mask创建完成后,下一步就是找到该Rule应属的哈希表,或者创建一个新的哈希表。

再接下来,为了将这个Rule添加进哈希表中,就需要先计算这个Rule的散列值,流程如下图所示:

 

上图将Rule #1添加进了名为HT 1的哈希表中,除了Rule #1外,HT 1这张表中还会存储很多与Rule #1相似的规则,而所谓相似,就是指它们位于同一个tuple中,换名话说,即是这些Rule对应的Mask都相同

即下面这个Rule也会被添加进HT 1中,所有同一个哈希表中的Rule的Mask都是相同的

1 Rule #1A: Src IP="83.83.83.*"

4.1.2. 查找匹配过程

现在有一个包被收上来,其源IP地址为21.2.10.99,我们称这个包为Packet #1,假设现在OVS的dpcls中除了HT 1之外没有其它的哈希表,那么这个包将在该表中进行匹配搜索操作。

首先会将该包与Mask #1进行与操作,将与操作的操作结构进行散列运算,得到散列值,然后就查出结果了。如下图所示

 

4.1.3. 添加第二个Rule

现在假设我们要添加第二个Rule,有了前面第一个Rule如何添加的阐述,这里就不阐述的那么详细了。这次要添加的Rule依然是源IP地址匹配,但掩码变成了16位:

1 Rule #2: Src IP = "7.2.*.*"

该Rule的对应的Mask是一个全新的Mask

1 Mask #2: 0xFF.FF.00.00

这是一个全新的Mask,意味着这个Rule属于一个全新的tuple,一个新的哈希表会被创建,之后该Rule会被插入到新的哈希表中,我们记这个新的哈希表为HT 2。整个插入过程如下图所示:

 

4.1.4. 第二次查找匹配

现在收上来一个包,其源IP地址为7.2.45.67,我们记该包为Packet #2
现在dpcls中有两个哈希表,匹配查找将试图在这两个表上都执行,直到成功匹配为止。我们假设HT 1是首个被执行搜索的哈希表,则显然会查找失败,其查找匹配过程如下:

 

由于查找匹配失败,所以匹配流程将继续在HT 2上执行,流和如下:

 

这一次匹配成功!

 

4.1.5. 小结

通过上面的图例与阐述,重新温习了TSS分类器的分类算法,也认识了OVS+DPDK对于TSS分类器的实现。但故事依然没有结束,在上面的例子中,整个OVS+DPDK的中间层仅有一个dpcls实例,所有OVS收到的包都由这个dpcls进行匹配查找操作,这样做是可行的,但与实际情况并不符合。前文说过,在2.6版本之后,OVS为每个ovs-port都创建了一个dpcls实例,下面我们将继续分析在多port多dpcls实例的情景下,Rule是如何被插入的,包是如何被匹配的。

 

4.2. 多ovs-port场景

下图展示了两个PMD线程(PMD60与PMD63),两个ovs-port(port0与port3),port0由pmd60负责收包,port3由pmd63负责收包,每个port都有自己的dpcls实例与EMC缓存。这种场景下发生的故事:

1) 假设有两个包到达了port0,其源IP地址分别是21.2.10.99与7.2.45.67,其假设上一章阐述的故事均发生在port0上

2) 即port0的dpcls中会有两个tuple/哈希表,且其EMC中分别存储着源IP地址为21.2.10.99与7.2.45.67这两个包的action

3) 有一个包到达了port3,其源IP地址为5.5.5.1,包收上来之后在port3下的dpcls中生成了一个5.5.0.0/16的rule

4) 现在继续收包,port0上收到一个源IP地址为21.2.10.2的包,EMC中查无记录,于是去dpcls中查找,查找过程如上一章所述,如果运气不好的话需要查找两张哈希表。查找匹配成功后除了包将被转发出去,也会在EMC中下该包的缓存。

5) port3上收到一个源IP地址为5.5.5.8的包,EMC中查无记录,上dpcls查找,一次命中。包被转发,同时下EMC缓存

 

转载于:https://www.cnblogs.com/neooelric/p/7160222.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/487984.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql第五章 在线测试_PHP+MySQL来实现在线测试quiz功能

在上一篇文章中,我们介绍了jQuery前端PHP在线测试题效果。这篇文章将结合实例给大家介绍如何使用jQueryPHPMySQL来实现在线测试题,包括动态读取题目,答题完毕后台评分,并返回答题结果。查看演示下载资源:1332次 下载资…

深度揭秘AI换脸原理,为啥最先进分类器也认不出?

文章来源:VentureBeat,arXiv智东西4月20日消息,AI换脸已不是新鲜事,手机应用市场中有多款换脸app,此前也曾曝出有网络IP用明星的面孔伪造色情影片、在大选期间用竞选者的脸制作虚假影像信息等。为了规避Deepfake滥用带…

中美德工业互联网路径比较

转自丨无锡情报所作者丨王喜文,九三学社中央促进技术创新工作委员会委员、九三学社中央科技委委员过去20年,互联网是改变社会、改变商业最重要的技术;如今,随着5G、物联网以及云计算和大数据、区块链、人工智能技术的迅速发展&…

不同浏览器隐藏默认表单样式

各种appearance: none; 转载于:https://www.cnblogs.com/haimingpro/p/7168738.html

jmeter file upload 变量_通达OA上传漏洞之变量覆盖分析

作者:kw0ng开始通达OA上传到包含漏洞分析的文章已经有很多,本文重点分析,文件上传处决定路径信息是否回显的UPLOAD_MODE参数是怎么传递的。代码分析触发文件上传点位于/ispirit/im/upload.php中,服务端在接收文件信息的同时还需要…

如果卷积神经网络存在根本性的缺陷,你会怎么看?

来源:人工智能头条作者 | Ben Dickson译者 | 香槟超新星经过一段漫长时期的沉寂之后,人工智能正在进入一个蓬勃发展的新时期,这主要得益于深度学习和人工神经网络近年来取得的长足发展。更准确地说,人们对深度学习产生的新的兴趣在…

产业|嵌入式传感器将是未来机器人等技术增长的核心

来源:EEWORLD移动即服务(MaaS)被认为是智能移动的一个关键要素,而机器人汽车技术将是智能移动的一个重要因素,它又高度依赖于嵌入式传感器。根据市场研究和战略咨询公司Yole development pement (Yole)的预测,在这种情况下&#x…

可观测宇宙中,我们可能是唯一的生命

图片来源:Pixabay长期以来,人类一直渴望在宇宙中找到地外生命的痕迹,但一项于今年早些时候发表的研究,给持有此类想法的人泼了一盆冷水。基于“自然发生”学说以及其中的“RNA世界”假说,研究人员认为在可观测宇宙中&a…

中国工程院发布“中国电子信息工程科技发展十六大挑战”

来源:通信世界全媒体通信世界网消息(CWW)为响应中央决策部署,推进我国新型数字基础设施建设,推动我国电子信息工程科技领域高质量发展,助力数字基建科学发展驱动壮大经济新动能。4月26日,中国工程院信息与电子学部、中…

Unix下5种I/O模型

Unix下I/O模型主要分为5种: (1)阻塞式I/O (2)非阻塞式I/O (3)I/O复用(select和poll) (4)信号驱动式I/O (5)异步I/O 1、阻塞式I/O模型 unix基本的套…

2019年智能科学与产业综述论文盘点

来源:计算机研究与发展2019年综述论文盘点1.智能芯片的评述和展望(韩栋,周聖元,支天,陈云霁,陈天石)2.闪存存储的重构与系统构建技术(陆游游,杨者,舒继武)3.基于动态权衡的新型非易失存储器件体系结构研究综述&#xf…

h命令可以获取mysql客户端的帮助信息_如何获取MySQL帮助信息

在开发或测试环境在碰到MySQL相关故障时,大多数朋友可能会通过论坛发帖,QQ群讨论方式来获取帮助。该方式是获取帮助的有效途径之一。然而如果在生产环境,在没有网络的环境下,这些方式就无助于问题的解决。无论何种数据库&#xff…

AI与人类围棋士的差距到底有多大?

来源:计算广告四年前,谷歌旗下DeepMind公司开发的围棋人工智能AlphaGo以4-1战胜韩国大国手李世乭九段。今天,AlphaGo在大众视野中掀起的惊涛骇浪已渐平息,AlphaGo和李世乭都已从江湖退隐。然而,围棋界因AlphaGo而起的沧…

mariadb使用mysql驱动_MariaDB安装与使用

下载相对应的电脑版本程序等待下载完成......安装教程:双击运行设置数据库的密码等待安装完成..这样就完成安装了。安装完成,会在桌面生成这个图标双击可以直接使用下面我通过两种方式来使用MariaDB数据库(可视化,命令行)通过可视化方式使用。…

脑机接口技术重大突破!首次帮助瘫痪男子恢复运动和触觉

来源:网易智能触觉是我们感受外部世界不可或缺的感官,但许多人却因脊髓损伤或因患病瘫痪而失去这种能力。不过,最近非营利组织巴特尔研究所的研究人员宣称,他们首次利用脑机接口(BCI)技术帮助一名美国瘫痪男…

python海龟图画龙珠_火影,海贼王,七龙珠,还在为漫画书发愁!我用Python一键生成电子漫画书...

小时候看漫画都是要买书的,一本好几块钱,成本那个高啊后来可以在线看漫画,感觉真是爽不过近几年新的问题又出现了:漫画网站广告太多,更重要的是越来越多的作品、章节出于各种原因被下架、限制观看。为了提升观看体验&a…

谷歌自揭“家丑”:医疗AI实验室表现超神,临床结果却不佳

来源:澎湃新闻在医疗领域,尤其是在医学影像筛查过程中,人工智能常被描述为完美的工作者。它们能准确识别疾病,拥有人类专家级的发现能力,还不知疲倦。但与许多技术一样,在实验室取得成功是一回事&#xff0…

mysql 移植ucos_基于STM32F767的UCOSIII移植学习

(一)移植前的准备1.HAL库基本工程模板新建一个工程模块,其中包含LED驱动和串口驱动程序即可,用于验证UCOS-III系统能够正常工作。2.UCOS-III源码准备去Micrium官网下载最新的UCOSIII源码,下载地址:Micrium官网下载地址&#xff0c…

美国5G到底怎么了?

来源:网优雇佣军美国司法部长威廉巴尔(William Barr)在2月6日应华盛顿智库“战略与国际研究中心”(CSIS, Center for Strategic & International Studies)邀请,参加了“中国倡议”会议(Chin…

SQL实践篇(一):使用WebSQL在H5中存储一个本地数据库

文章目录 简介本地存储都有哪些?如何使用WebSQL打开数据库事务操作SQL执行 在浏览器端做一个英雄的查询页面如何删除本地存储参考文献 简介 WebSQL是一种操作本地数据库的网页API接口,通过它,我们可以操作客户端的本地存储。 WebSQL曾经是H…