绝对干货!初学者也能看懂的DPDK解析

2023-11-12

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~

本文由Willko发表于云+社区专栏

一、网络IO的处境和趋势

从我们用户的使用就可以感受到网速一直在提升,而网络技术的发展也从1GE/10GE/25GE/40GE/100GE的演变,从中可以得出单机的网络IO能力必须跟上时代的发展。

1. 传统的电信领域

IP层及以下,例如路由器、交换机、防火墙、基站等设备都是采用硬件解决方案。基于专用网络处理器(NP),有基于FPGA,更有基于ASIC的。但是基于硬件的劣势非常明显,发生Bug不易修复,不易调试维护,并且网络技术一直在发展,例如2G/3G/4G/5G等移动技术的革新,这些属于业务的逻辑基于硬件实现太痛苦,不能快速迭代。传统领域面临的挑战是急需一套软件架构的高性能网络IO开发框架。

2. 云的发展

私有云的出现通过网络功能虚拟化(NFV)共享硬件成为趋势,NFV的定义是通过标准的服务器、标准交换机实现各种传统的或新的网络功能。急需一套基于常用系统和标准服务器的高性能网络IO开发框架。

3. 单机性能的飙升

网卡从1G到100G的发展,CPU从单核到多核到多CPU的发展,服务器的单机能力通过横行扩展达到新的高点。但是软件开发却无法跟上节奏,单机处理能力没能和硬件门当户对,如何开发出与时并进高吞吐量的服务,单机百万千万并发能力。即使有业务对QPS要求不高,主要是CPU密集型,但是现在大数据分析、人工智能等应用都需要在分布式服务器之间传输大量数据完成作业。这点应该是我们互联网后台开发最应关注,也最关联的。

二、Linux + x86网络IO瓶颈

在数年前曾经写过《网卡工作原理及高并发下的调优》一文,描述了Linux的收发报文流程。根据经验,在C1(8核)上跑应用每1W包处理需要消耗1%软中断CPU,这意味着单机的上限是100万PPS(Packet Per Second)。从TGW(Netfilter版)的性能100万PPS,AliLVS优化了也只到150万PPS,并且他们使用的服务器的配置还是比较好的。假设,我们要跑满10GE网卡,每个包64字节,这就需要2000万PPS(注:以太网万兆网卡速度上限是1488万PPS,因为最小帧大小为84B《Bandwidth, Packets Per Second, and Other Network Performance Metrics》),100G是2亿PPS,即每个包的处理耗时不能超过50纳秒。而一次Cache Miss,不管是TLB、数据Cache、指令Cache发生Miss,回内存读取大约65纳秒,NUMA体系下跨Node通讯大约40纳秒。所以,即使不加上业务逻辑,即使纯收发包都如此艰难。我们要控制Cache的命中率,我们要了解计算机体系结构,不能发生跨Node通讯。

从这些数据,我希望可以直接感受一下这里的挑战有多大,理想和现实,我们需要从中平衡。问题都有这些

1.传统的收发报文方式都必须采用硬中断来做通讯,每次硬中断大约消耗100微秒,这还不算因为终止上下文所带来的Cache Miss。

2.数据必须从内核态用户态之间切换拷贝带来大量CPU消耗,全局锁竞争。

3.收发包都有系统调用的开销。

4.内核工作在多核上,为可全局一致,即使采用Lock Free,也避免不了锁总线、内存屏障带来的性能损耗。

5.从网卡到业务进程,经过的路径太长,有些其实未必要的,例如netfilter框架,这些都带来一定的消耗,而且容易Cache Miss。

三、DPDK的基本原理

从前面的分析可以得知IO实现的方式、内核的瓶颈,以及数据流过内核存在不可控因素,这些都是在内核中实现,内核是导致瓶颈的原因所在,要解决问题需要绕过内核。所以主流解决方案都是旁路网卡IO,绕过内核直接在用户态收发包来解决内核的瓶颈。

Linux社区也提供了旁路机制Netmap,官方数据10G网卡1400万PPS,但是Netmap没广泛使用。其原因有几个:

1.Netmap需要驱动的支持,即需要网卡厂商认可这个方案。

2.Netmap仍然依赖中断通知机制,没完全解决瓶颈。

3.Netmap更像是几个系统调用,实现用户态直接收发包,功能太过原始,没形成依赖的网络开发框架,社区不完善。

那么,我们来看看发展了十几年的DPDK,从Intel主导开发,到华为、思科、AWS等大厂商的加入,核心玩家都在该圈子里,拥有完善的社区,生态形成闭环。早期,主要是传统电信领域3层以下的应用,如华为、中国电信、中国移动都是其早期使用者,交换机、路由器、网关是主要应用场景。但是,随着上层业务的需求以及DPDK的完善,在更高的应用也在逐步出现。

DPDK旁路原理:

img图片引自Jingjing Wu的文档《Flow Bifurcation on Intel® Ethernet Controller X710/XL710》

左边是原来的方式数据从 网卡 -> 驱动 -> 协议栈 -> Socket接口 -> 业务

右边是DPDK的方式,基于UIO(Userspace I/O)旁路数据。数据从 网卡 -> DPDK轮询模式-> DPDK基础库 -> 业务

用户态的好处是易用开发和维护,灵活性好。并且Crash也不影响内核运行,鲁棒性强。

DPDK支持的CPU体系架构:x86、ARM、PowerPC(PPC)

DPDK支持的网卡列表:https://core.dpdk.org/supported/,我们主流使用Intel 82599(光口)、Intel x540(电口)

四、DPDK的基石UIO

为了让驱动运行在用户态,Linux提供UIO机制。使用UIO可以通过read感知中断,通过mmap实现和网卡的通讯。

UIO原理:

img

要开发用户态驱动有几个步骤:

1.开发运行在内核的UIO模块,因为硬中断只能在内核处理

2.通过/dev/uioX读取中断

3.通过mmap和外设共享内存

五、DPDK核心优化:PMD

DPDK的UIO驱动屏蔽了硬件发出中断,然后在用户态采用主动轮询的方式,这种模式被称为PMD(Poll Mode Driver)。

UIO旁路了内核,主动轮询去掉硬中断,DPDK从而可以在用户态做收发包处理。带来Zero Copy、无系统调用的好处,同步处理减少上下文切换带来的Cache Miss。

运行在PMD的Core会处于用户态CPU100%的状态

img

网络空闲时CPU长期空转,会带来能耗问题。所以,DPDK推出Interrupt DPDK模式。

Interrupt DPDK:

img图片引自David Su/Yunhong Jiang/Wei Wang的文档《Towards Low Latency Interrupt Mode DPDK》

它的原理和NAPI很像,就是没包可处理时进入睡眠,改为中断通知。并且可以和其他进程共享同个CPU Core,但是DPDK进程会有更高调度优先级。

六、DPDK的高性能代码实现

1. 采用HugePage减少TLB Miss

默认下Linux采用4KB为一页,页越小内存越大,页表的开销越大,页表的内存占用也越大。CPU有TLB(Translation Lookaside Buffer)成本高所以一般就只能存放几百到上千个页表项。如果进程要使用64G内存,则64G/4KB=16000000(一千六百万)页,每页在页表项中占用16000000 * 4B=62MB。如果用HugePage采用2MB作为一页,只需64G/2MB=2000,数量不在同个级别。

而DPDK采用HugePage,在x86-64下支持2MB、1GB的页大小,几何级的降低了页表项的大小,从而减少TLB-Miss。并提供了内存池(Mempool)、MBuf、无锁环(Ring)、Bitmap等基础库。根据我们的实践,在数据平面(Data Plane)频繁的内存分配释放,必须使用内存池,不能直接使用rte_malloc,DPDK的内存分配实现非常简陋,不如ptmalloc。

2. SNA(Shared-nothing Architecture)

软件架构去中心化,尽量避免全局共享,带来全局竞争,失去横向扩展的能力。NUMA体系下不跨Node远程使用内存。

3. SIMD(Single Instruction Multiple Data)

从最早的mmx/sse到最新的avx2,SIMD的能力一直在增强。DPDK采用批量同时处理多个包,再用向量编程,一个周期内对所有包进行处理。比如,memcpy就使用SIMD来提高速度。

SIMD在游戏后台比较常见,但是其他业务如果有类似批量处理的场景,要提高性能,也可看看能否满足。

4. 不使用慢速API

这里需要重新定义一下慢速API,比如说gettimeofday,虽然在64位下通过vDSO已经不需要陷入内核态,只是一个纯内存访问,每秒也能达到几千万的级别。但是,不要忘记了我们在10GE下,每秒的处理能力就要达到几千万。所以即使是gettimeofday也属于慢速API。DPDK提供Cycles接口,例如rte_get_tsc_cycles接口,基于HPET或TSC实现。

在x86-64下使用RDTSC指令,直接从寄存器读取,需要输入2个参数,比较常见的实现:

static inline uint64_t
rte_rdtsc(void)
{
      uint32_t lo, hi;

      __asm__ __volatile__ (
                 "rdtsc" : "=a"(lo), "=d"(hi)
                 );

      return ((unsigned long long)lo) | (((unsigned long long)hi) << 32);
}

这么写逻辑没错,但是还不够极致,还涉及到2次位运算才能得到结果,我们看看DPDK是怎么实现:

static inline uint64_t
rte_rdtsc(void)
{
    union {
        uint64_t tsc_64;
        struct {
            uint32_t lo_32;
            uint32_t hi_32;
        };
    } tsc;

    asm volatile("rdtsc" :
             "=a" (tsc.lo_32),
             "=d" (tsc.hi_32));
    return tsc.tsc_64;
}

巧妙的利用C的union共享内存,直接赋值,减少了不必要的运算。但是使用tsc有些问题需要面对和解决

1) CPU亲和性,解决多核跳动不精确的问题

2) 内存屏障,解决乱序执行不精确的问题

3) 禁止降频和禁止Intel Turbo Boost,固定CPU频率,解决频率变化带来的失准问题

5. 编译执行优化

1) 分支预测

现代CPU通过pipelinesuperscalar提高并行处理能力,为了进一步发挥并行能力会做分支预测,提升CPU的并行能力。遇到分支时判断可能进入哪个分支,提前处理该分支的代码,预先做指令读取编码读取寄存器等,预测失败则预处理全部丢弃。我们开发业务有时候会非常清楚这个分支是true还是false,那就可以通过人工干预生成更紧凑的代码提示CPU分支预测成功率。

#pragma once

#if !__GLIBC_PREREQ(2, 3)
#    if !define __builtin_expect
#        define __builtin_expect(x, expected_value) (x)
#    endif
#endif

#if !defined(likely)
#define likely(x) (__builtin_expect(!!(x), 1))
#endif

#if !defined(unlikely)
#define unlikely(x) (__builtin_expect(!!(x), 0))
#endif

2) CPU Cache预取

Cache Miss的代价非常高,回内存读需要65纳秒,可以将即将访问的数据主动推送的CPU Cache进行优化。比较典型的场景是链表的遍历,链表的下一节点都是随机内存地址,所以CPU肯定是无法自动预加载的。但是我们在处理本节点时,可以通过CPU指令将下一个节点推送到Cache里。

API文档:https://doc.dpdk.org/api/rte__prefetch_8h.html

static inline void rte_prefetch0(const volatile void *p)
{
    asm volatile ("prefetcht0 %[p]" : : [p] "m" (*(const volatile char *)p));
}
#if !defined(prefetch)
#define prefetch(x) __builtin_prefetch(x)
#endif

…等等

3) 内存对齐

内存对齐有2个好处:

l 避免结构体成员跨Cache Line,需2次读取才能合并到寄存器中,降低性能。结构体成员需从大到小排序和以及强制对齐。参考《Data alignment: Straighten up and fly right

#define __rte_packed __attribute__((__packed__))

l 多线程场景下写产生False sharing,造成Cache Miss,结构体按Cache Line对齐

#ifndef CACHE_LINE_SIZE
#define CACHE_LINE_SIZE 64
#endif

#ifndef aligined
#define aligined(a) __attribute__((__aligned__(a)))
#endif

4) 常量优化

常量相关的运算的编译阶段完成。比如C++11引入了constexp,比如可以使用GCC的__builtin_constant_p来判断值是否常量,然后对常量进行编译时得出结果。举例网络序主机序转换

#define rte_bswap32(x) ((uint32_t)(__builtin_constant_p(x) ?        \
                   rte_constant_bswap32(x) :        \
                   rte_arch_bswap32(x)))

其中rte_constant_bswap32的实现

#define RTE_STATIC_BSWAP32(v) \
    ((((uint32_t)(v) & UINT32_C(0x000000ff)) << 24) | \
     (((uint32_t)(v) & UINT32_C(0x0000ff00)) <<  8) | \
     (((uint32_t)(v) & UINT32_C(0x00ff0000)) >>  8) | \
     (((uint32_t)(v) & UINT32_C(0xff000000)) >> 24))

5)使用CPU指令

现代CPU提供很多指令可直接完成常见功能,比如大小端转换,x86有bswap指令直接支持了。

static inline uint64_t rte_arch_bswap64(uint64_t _x)
{
    register uint64_t x = _x;
    asm volatile ("bswap %[x]"
              : [x] "+r" (x)
              );
    return x;
}

这个实现,也是GLIBC的实现,先常量优化、CPU指令优化、最后才用裸代码实现。毕竟都是顶端程序员,对语言、编译器,对实现的追求不一样,所以造轮子前一定要先了解好轮子。

Google开源的cpu_features可以获取当前CPU支持什么特性,从而对特定CPU进行执行优化。高性能编程永无止境,对硬件、内核、编译器、开发语言的理解要深入且与时俱进。

七、DPDK生态

对我们互联网后台开发来说DPDK框架本身提供的能力还是比较裸的,比如要使用DPDK就必须实现ARP、IP层这些基础功能,有一定上手难度。如果要更高层的业务使用,还需要用户态的传输协议支持。不建议直接使用DPDK。

目前生态完善,社区强大(一线大厂支持)的应用层开发项目是FD.io(The Fast Data Project),有思科开源支持的VPP,比较完善的协议支持,ARP、VLAN、Multipath、IPv4/v6、MPLS等。用户态传输协议UDP/TCP有TLDK。从项目定位到社区支持力度算比较靠谱的框架。

腾讯云开源的F-Stack也值得关注一下,开发更简单,直接提供了POSIX接口。

Seastar也很强大和灵活,内核态和DPDK都随意切换,也有自己的传输协议Seastar Native TCP/IP Stack支持,但是目前还未看到有大型项目在使用Seastar,可能需要填的坑比较多。

我们GBN Gateway项目需要支持L3/IP层接入做Wan网关,单机20GE,基于DPDK开发。

问答
如何检查网络连接?

相关阅读
把报文再扔回内核,DPDK这样做
用DPDK rte_ring实现多进程间通信
低于0.01%的极致Crash率是怎么做到的?
【每日课程推荐】新加坡南洋理工大学博士,带你深度学习NLP技术

此文已由作者授权腾讯云+社区发布,更多原文请点击

搜索关注公众号「云加社区」,第一时间获取技术干货,关注后回复1024 送你一份技术课程大礼包!

海量技术实践经验,尽在云加社区

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

绝对干货!初学者也能看懂的DPDK解析 的相关文章

  • 在 Google Cloud 中设置网站? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我完全迷失在这之中 我习惯于使用带有 cpanel 的简单 Web 主机来制作网站 只需使用 filezilla 登录并上传我的 ht
  • REST API 与 Web API

    我是构建 HTTP API 的初学者 我似乎对 REST API 和 Web API 之间的区别感到困惑 我在网上读到更多相关内容 困惑似乎越来越多 我猜菲尔丁有与此链接相同的问题http roy gbiv com untangled 20
  • 网页编码,设置矛盾[重复]

    这个问题在这里已经有答案了 如果一个网页有 但http标头有 Content Type text html charset UTF 8 那么假设什么编码呢 在 HTML5 中 优先级定义为 用户浏览器设置 字节顺序标记 HTTP 标头 or
  • 执行预检请求时是否需要 Access-Control-Allow-Origin CORS 标头?

    我们在我们的网站上看到了著名的 CORS 错误 XMLHttpRequest 无法加载https my site com api https my site com api 请求的资源上不存在 Access Control Allow Or
  • 最长和最短的 HTML 字符实体名称是什么? [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 管子周围有
  • 清除 Laravel 队列缓存而不重新启动

    在我的应用程序中 每个客户都有一种复杂的类 我们在其中为该特定客户进行一些搜索和替换 我运行队列工作人员每天与 eBay 同步 以便每个客户进行某种搜索和替换 问题是 Laravel 队列会缓存代码很长一段时间 如果我想去更改任何客户类文件
  • 当url中有空格时htaccess重定向

    我想从仍然出现在谷歌搜索中的旧网址重定向到新网址 旧的网址是这样的 http www marionettecolla org file 20 mostra milano mostra marionette milano htm 我想将其重定
  • 使用 hg 存储库作为网站

    这与我的安全问题有些相关here https stackoverflow com questions 2361626 security deny access to hg via mod rewrite 对实时网站使用 hg Mercuri
  • 使用 REST API 进行正确的会话管理

    我已经完成了 RESTful API 的设计 其中我使用作为参数发送的 API 令牌对每个请求进行身份验证 现在我想创建一个客户端界面 我想知道什么是管理每个客户端的会话的正确安全方法browser客户 我想过一个流程来保持服务器端无状态
  • 电话链接在 iframe 中不起作用,但在 iOS 9 Web 中的 div 中起作用。如何使电话链接在 iOS 9 safari 中正常工作?

    您好 我正在尝试 iOS9 中 iframe 内的电话链接 iOS9 中的 safari 中无法打开手机应用程序 当我在里面尝试相同的链接时 它就在那里工作 我正在尝试下面的锚标记 将此代码放入 div 中时会打开手机应用程序 但同样的代码
  • Jekyll 在子网站上生成静态网站?

    是否可以将 Jekyll 放在 GitHub 上托管的网站的单个部分上 即是否可以让 example github io 成为常规站点 而 example github io blog 由 Jekyll 静态生成 我相信可以通过创建另一个名
  • Web Api - 不允许捕获 405 方法

    截至目前 Web api 应用程序针对 405 方法不允许错误返回以下响应正文 我正在尝试更改响应正文 但我不知道如何使用委托处理程序 ApiControllerActionSelector 或过滤器 谁能帮我捕获服务器端的 405 错误
  • 为什么要使用除 div 以外的任何东西? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 烧瓶 - 404 未找到

    我是烧瓶开发的新手 这是我在烧瓶中的第一个程序 但它向我显示了这个错误 在服务器上找不到请求的 URL 如果您输入了网址 请手动检查拼写并重试 这是我的代码 from flask import Flask app Flask name ap
  • 诸如用于测试 HTTP 请求的虚拟 REST 服务器之类的东西? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我一直在四处寻找 但找不到任何这样的网站 我想知道是否有一些虚拟服务器可以响应测试 GET 请求并返回
  • Chrome:网络元素自动移动

    我正在开发一个网络项目 在过去的两周里 我正在进行学期考试 所以我要休息一下 现在 既然他们已经结束了 我又继续我的工作了 但我发现我的一些Web 元素 如按钮 span 在 Chrome 上移动了一些像素 在 IE 和 Mozilla 上
  • IIS 8 HTTPS/需要 SSL 导致超时错误

    尝试通过 IIS 8 通过 SSL 发布网站 但出现超时错误 任何帮助表示赞赏 采取的步骤 已验证该网站可以通过 HTTP 访问 http xxx xxx xxx xxx有效 此时使用 IP 地址 如果重要的话 IIS gt 服务器证书 g
  • Web 应用程序使用 API 来完成一切?

    我即将开始为我的公司规划一个内部项目管理工具 API 一直让我疑惑 首先创建 API 并使用这些 API 调用构建实际站点而不是实施两次 是否会被视为不好的做法 效率太低 让我知道你的想法 我完全同意开发 API 将为您提供解耦的架构 并且
  • 如何获取dart中当前和调用函数的名称?

    C has System Reflection MethodBase GetCurrentMethod Name Dart 是否有类似的东西 但返回当前正在运行的函数以及调用当前运行函数的函数的名称的结果 我编写了一个简单的类 它提供当前函
  • 找不到模块:错误:包路径。未从包中导出

    import firebase from firebase const firebaseConfig apiKey AIzaSyBOK7x5N5UnjY4TDqndzH7l5tvdNIsWFRc authDomain todo app e3

随机推荐

  • C++ 排序函数 sort(),qsort()的用法

    C库函数qsort C 库函数sort 其中qsort相对较慢 sort实现非常高效 qsort 功 能 使用 快速排序例程进行排序 头文件 include
  • 锐浪报表-实现导入导出

    锐浪报表 实现导入导出 实现思路 代码实现 实现思路 导入导出实现思路 我们使用锐浪报表自带的导出功能导出 XX grf 后 鼠标右键是可以像编辑文本一样编辑内容的 由此联想到 用记事本手写一个模板改一下后缀名是不是也可以当作报表模板 答案
  • 好消息:vue3.3发布了,来看看更新那些功能

    前言 vue3 3发布了 来看看更新那些功能 原英文地址 Announcing Vue 3 3 The Vue PointThe offical blog for the Vue js projecthttps blog vuejs org
  • 2023年完整版Java学习路线图

    目录 第一阶段 Java核心基础 第二阶段 数据库核心技术 第三阶段 Java Web内容 第四阶段 企业级框架讲解 第五阶段 分布式微服务架构 第六阶段 技能深入提升 第七阶段 企业级项目实战 Java学习路线图 以下是我为您提供的原创J
  • NOIP学习之顺序查找:145.找最大数序列

    测试链接 总时间限制 1000ms 内存限制 65536kB 描述 输入n行 每行不超过100个无符号整数 无符号数不超过4位 请输出最大整数以及最大整数所在的行号 行号从1开始 如果该数据在多个行中出现 则按从小到大输出相应行号 行号之间
  • 【计算机视觉

    文章目录 一 MnasNet 二 GhostNet 三 Compact Convolutional Transformers CCT 四 NesT 五 Res2Net 六 EfficientNetV2 七 Capsule Network 八
  • JQuery安装与下载教程

    jQuery安装与下载 JQuery 是一个javaScript库 是一个轻量级的 写的少 做的多 的JavaScript库 jQuery 极大地简化javaScript编程 juery相比js优点 jquery的onload加载事件速度更
  • 方波转为正弦波的简单方案简介

    将方波信号转化为正弦波信号 主要是需要抑制方波信号的谐波信号 主要是抑制三次谐波 经过仿真测试 能够将方波转化为正弦波的滤波器 其衰减必须足够陡峭 将谐波频率尽可能压掉 在实际的滤波器中 经过测试 采用椭圆低通滤波器是能够实现所需要的滤波功
  • 【C++】STL常用容器总结之四:链表list

    5 链表list List是每个节点包含前驱指针 后继指针和数据域三个部分的双向链表 List不提供随机存取 访问元素需要按顺序走到需存取的元素 时间复杂度为O n 在list的任何位置上执行插入或删除操作都非常迅速 只需在list内部调整
  • 单目标优化:飞狐优化算法(Flying Foxes Optimization,FFO)求解cec2017(提供Matlab代码)

    一 飞狐优化算法简介 飞狐优化算法 Flying Foxes Optimization FFO 由Konstantinos Zervoudakis与Stelios Tsafarakis于2022年提出 参考文献 Zervoudakis K
  • 冒泡排序与快速排序【C语言】

    冒泡排序 基本思想 对有n个记录的序列进行冒泡排序 首先将第一个数字与第二个数字进行比较 若为逆序 则将两个数字的顺序交换 然后比较第二个数字与第三个数字 若为逆序 则将两个数字的顺序交换 依此类推 经过第一轮排序后 最大的数字将 下沉 到
  • PHP进行中文URL编转码为GB2312或UTF8

    中文转URL编码 GB2312 urlencode iconv utf 8 gb2312 中国人 中文转URL编码 UTF8 urlencode 中国人
  • ubuntu磁盘扩容方法(简单有效)

    准备工作 使用Vmware进行扩展 在进行磁盘扩展的时候 虚拟机不可以有快照 使用快照管理删除快照 开始扩容 点击 虚拟机 设置 硬盘 扩展 填写扩展大小 分区设置 扩展完成后并还需要在操作系统进行设置才能真正使用 下面有几种方法 第一种方
  • 运行开源库CCPD-RPnet代码,提示「KeyError: Caught KeyError in replica 0 on device 0」错误

    文章目录 问题描述 问题排查 Solution Other 问题描述 通过python3 demo py i demo m models fh02 pth运行车牌识别CCPD开源代码 提示 KeyError Caught KeyError
  • Spark

    1 Spark概述 Spark是一个支持多语言的数据计算 科学计算 机器学习引擎 同时支持单节点或者集群运行模式 其强大的功能包括 批处理 结构化的SQL计算 流式计算 机器学习库 图计算等 2 Spark集群环境的搭建 1 下载解压安装包
  • 骑士周游问题

    算法 1 骑士周游问题 马踏棋盘算法也被称为骑士周游问题 将马随机放在国际象棋的 8x8 棋盘中 0 7 0 7 的某个方格中 马鞍走起规则 马走日字 进行移动 要求每个方格只进入一次 走遍棋盘上全部64个方格 3 会使用到图的遍历算法 D
  • 【Ansible自动化运维实战】使用Asible批量部署Apache

    Ansible自动化运维实战 使用Asible批量部署Apache 一 本次实践目的 二 Plyabook内容 三 运行playbook 一 本次实践目的 将apache批量部署到被控节点 二 Plyabook内容 hosts node1
  • 嵌入式linux闹钟,嵌入式电子闹钟课程设计.doc

    嵌入式系统综合实验 题 目 基于嵌入式的数字闹钟系统设计 学生姓名 秦乙 学 号 20071309087 学 院 电子与信息工程学院 专 业 信息工程 二 一 年 十二 月 二十七 日 目 录 论文标题错误 未定义书签 摘要和关键词错误 未
  • 利用OpenCV的函数matchTemplate()实现在图像中寻找、检索、搜索模板图像【图像模板匹配】

    利用OpenCV的函数matchTemplate 实现在图像中寻找 检索 搜索模板图像 图像模板匹配 在博文 https www hhai cc thread 220 1 1 html 中我们利用直方图的反向投影原理可以寻找图像中具有某个直
  • 绝对干货!初学者也能看懂的DPDK解析

    欢迎大家前往腾讯云 社区 获取更多腾讯海量技术实践干货哦 本文由Willko发表于云 社区专栏 一 网络IO的处境和趋势 从我们用户的使用就可以感受到网速一直在提升 而网络技术的发展也从1GE 10GE 25GE 40GE 100GE的演变