DPDK的PMD(uio/igb_uio/vfio-pci/uio_pci_generic)

2023-11-07

linux收包的方式

Linux 内核在收包时有两种方式可供选择,一种是中断方式,另外一种是轮询方式。
从哲学的角度来说,中断是外界强加给你的信号,你必须被动应对,而轮询则是你主动地处理事情。前者最大的影响就是打断你当前工作的连续性,而后者则不会,事务的安排自在掌握。

中断对性能的影响有多大?

在 x86 体系结构中,一次中断处理需要:

将 CPU 的状态寄存器保存到堆栈;
运行中断服务程序;
再将保存的状态寄存器信息从堆栈中恢复。

整个过程需要至少 300 个处理器时钟周期。
所以:
网络中大量数据包到来时,会频繁产生中断请求,频繁的中断会造成上下文的切换产生时延,产生较高的性能开销。

轮询对性能的提升有多大?

网卡收到报文后,可以借助 DDIO(Direct Data I/O)技术直接将报文保存到 CPU 的 Cache 中,或者保存到内存中(没有 DDIO 技术的情况下),并设置报文到达的标志位。应用程序则可以周期性地轮询报文到达的标志位,检测是否有新报文需要处理。整个过程中完全没有中断处理过程,因此应用程序的网络报文处理能力得以极大提升。

  • 当前 Linux 内核为什么不使用轮询模式

轮询模式,会一直占用CPU去查询是否有包达到,即使在没有包到达的情况下。当前的Linux的CPU,不仅仅是收发包,还要为应用程序预留计算资源。所以轮询模式,适用于仅仅进行包转发,没有到应用层的的情况下。

当前内核协议栈可以使用 NAPI (中断+轮询)的方式,但依旧没有根本上解决问题。

在这里插入图片描述
这种PMD驱动并不适用于一般的应用场景,因为需要有专门的CPU给PMD一直做轮询操作,对应的CPU就会一直占用100%,可能严重影响了其他任务的运行。

当网络处于空闲状态的时候,CPU占用100%的问题会带来额外的不必要的功耗,因此dpdk还推出了一个interrupt dpdk模式,即当网卡中没有数据包处理的时候进入类似睡眠模式的状态,然后改为传统的中断方式通知,这个时候被100%占用的核心利用率就会降低,可以和其他的进程共享,但是DPDK仍然拥有高优先级,而当有数据包进来的时候还是可以优先处理。

PMD 介绍

PMD是Poll Mode Driver的缩写,即基于用户态的轮询机制的驱动。
在这里插入图片描述
参见:dpdk pmd 介绍

  • 我的理解
  • PMD 包含 PMD 应用程序(DPDK程序) + PMD KMOD(pmd kmod: 比如:igb_uio/uio_pci_generic/vfio_pci)
  • PMD应用程序「DPDK程序」在用户态调用API 接口对网卡进行配置,获取统计,收发包。

在这里插入图片描述
用户态部分实现真正的业务处理,内核态部分主要是接管硬件资源提供给用户态部分使用

如上:我将整个框架分了四层,用户层、接口层、内核层、硬件层。网卡开始是与e1000等网卡驱动绑定,当用户层程序执行解绑以及绑定命令,通过sysfs将消息发送至内核层后,网卡与igb_uio驱动进行了绑定。此时内核层uio接管了网卡,并为用户层pmd提供了服务接口。到此我们知道pmd的使用是需要内核层支持的。

  • DPDK应用如何基于PCI获取对应网卡驱动的配置、查询、收发包的API的?

1> DPDK程序 通过-w/-a 参数指定 pci
2> 基于pci 查询 该PCI上设备网卡对应的 Vendor-ID, Device-ID,进而可以知道对应的驱动。
3> 注册对应驱动的 DPDK API接口。
比如:识别为 ixgbe 驱动,rte_eth_dev_filter_ctrl 赋值为 ixgbe_dev_filter_ctrl。

linux 下基于 pci查询 vendor-id, device-id:
在这里插入图片描述
8086 为 vendor-id, 代表 intel.
10fb 为 device-id, 代表 82599ES.
在这里插入图片描述
在这里插入图片描述
参见:intel 8259x 系列网卡的 vendor-id,device-id 对照表

查看某个DPDK版本支持的驱动、网卡
./dpdk-pmdinfo.py -t ./dpvs
由于 dpvs 是通过制定版本的 dpdk 编译而成。
在这里插入图片描述在这里插入图片描述

  • 驱动对应的DPDK程序调用的用户态的API构成的DPDK lib库
    如下所示:用户态的一些库,提供了 API,共DPDK应用程序进行调用。
    DPDK程序需要包含这些库,才可以调用对应的API。
    在这里插入图片描述
    在这里插入图片描述

收包对比

在这里插入图片描述
PMD驱动包含了各种API,在用户态配置网卡和网卡的收发队列。

PWD驱动最大的优势就是无需任何中断操作就可以直接访问网卡队列中的RX/TX描述符(除了网卡的链接状态变化),借助这个优势,就可以绕过内核和同样运行在用户态的应用程序快速地进行数据传输。

这种绕过系统内核的做法最直接的代价就是驱动程序必须一直通过轮询poll的操作来保证能够及时接收到网卡的信息和数据,导致对应的cpu核心会一直处于100%的占用状态。同时这个时候网卡已经不再归于系统内核管理,常规的ip和ifconfig等命令已经没办法查看网卡的详细信息

内核收包的弊端

  • 中断处理:
    当网络中大量数据包到来时,会频繁产生中断请求,频繁的中断会产生较高的性能开销、并造成上下文的切换产生时延。
  • 内存拷贝
    网络数据包到来时,网卡通过 DMA 等拷贝到内核缓冲区,内核协议栈再从内核空间拷贝到用户态空间,在 Linux 内核协议栈中,这个耗时操作甚至占到了数据包整个处理流程的 57.1%。
  • 局部性失效
    目前主流处理器都是多个CPU核心的,这意味着一个数据包的处理可能跨多个 CPU 核心。比如:一个数据包可能中断在 cpu0,内核态处理在 cpu1,用户态处理在 cpu2,这样跨多个核心,容易造成 CPU 缓存失效,造成局部性失效。

DPDK 收包的优点

  • 整体流程

PMD Driver 从网卡上接收到数据包后,会直接通过 DMA 方式传输到预分配的内存中,同时更新无锁环形队列中的数据包指针,不断轮询的应用程序很快就能感知收到数据包,并在预分配的内存地址上直接处理数据包(减少内存拷贝),这个过程非常简洁。

  • 优点
  • 内核bypass
    通过UIO(Userspace I/O)旁路数据包,实现用户态数据包收发,减少内存拷贝;另外轮询方式收包代替中断方式,减少上下文切换。
  • CPU 的亲和性
    设置 CPU 的亲和性,将线程和 CPU 核进行一比一绑定,减少彼此之间调度切换,减少cache miss.
  • 使用大页内存代替普通的内存
    减少 cache-miss。
  • 采用无锁技术
    解决资源竞争问题。

uio/igb_uio/uio_pci_generic/vfio-pci

为了支持Userspace IO,DPDK可以选择如下三种类型的驱动:

- uio_pci_generic
- igb_uio
- vfio-pci

参见:Userspace IO
注:
igb_uio 完全可以代替 uio_pci_generic;
Mellanox 网卡比较特殊,不需要igb_uio等内核模块。

igb_uio

在这里插入图片描述
PMD是在用户态提供的API来操作,但还是依赖于内核提供的策略。

  • uio模块
    内核提供的用户态驱动框架。
  • igb_uio/uio_pci_generic
    IGB_UIO/uio_pci_generic(igb_uio.ko)是DPDK 用于与 UIO 交互的内核模块,通过 IGB_UIO/uio_pci_generic 来 bind 指定的 PCI 网卡设备给到用户态的 PMD 使用。可以认为 igb_uio/uio_pci_generic 是 uio 模块的一个实例。
    IGB_UIO/uio_pci_generic 借助 UIO 技术来截获中断,并重设中断回调行为,从而绕过内核协议栈后续的处理流程。
    IGB_UIO/uio_pci_generic 会在内核初始化的过程中将网卡硬件寄存器映射到用户态。

igb_uio/uio_pci_generic 是一种 pci 驱动,将网卡绑定到 igb_uio 隔离了网卡的内核驱动,同时 igb_uio 完成网卡中断内核态初始化并将中断信号映射到用户态。
比如:网卡在内核中使用 ice/ixgbe 内核驱动,如果通过 dpdk-devbind 解绑定内核驱动 ice/ixgbe, 然后使用 igb_uio进行接管网卡。这样dpdk应用程序会使用dpdk的 ice/ixgbe pmd ,底层是igb_uio /uio 来进行收发包。
dpdk的 ice/ixgbe pmd 代码可以在dpdk 源码中查看。
注:一旦dpdk应用使用 ice/ixgbe pmd + igb_uio + uio 进行收发包,那么和内核原生的驱动 ixgbe/ice 就没有关系了

IGB_UIO 内核模块主要功能:

  • 用于注册一个 PCI 设备。
    通过 DPDK 提供个 Python 脚本 dpdk-devbind 来完成,当执行 dpdk-devbind 来 bind 网卡时,会通过 sysfs 与内核交互,让内核使用指定的驱动程序(e.g. igb_uio)来绑定网卡。
    在 Linux 中,将设备(Device)与驱动(Driver)进行绑定的方法有两种:
  • 配置设备
    让其选择驱动:向 /sys/bus/pci/devices/{pci id}/driver_override 写入指定驱动的名称。
  • 配置驱动
    让其支持新的 PCI 设备:向 /sys/bus/pci/drivers/igb_uio/new_id 写入要 bind 的网卡设备的 PCI ID(e.g. 8086 10f5,格式为:设备厂商号 设备号)。

按照内核的文档 https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-bus-pci 中提到,这两个动作都会促使驱动程序 bind 新的网卡设备,而 DPDK 显然是使用了第 2 种方式。

  • 让用户态的 PMD 网卡驱动程序(DPDK程序)得以与 UIO 进行交互
  • 调用 igbuio_setup_bars,设置 uio_info 的 uio_mem 和 uio_port。
  • 设置 uio_info 的其他成员。
  • 调用 uio_register_device,注册 UIO 设备。
  • 打开 UIO 设备并注册中断。
  • 调用 uio_event_notify,将注册的 UIO 设备的 “内存空间” 映射到用户态的应用空间。
    其 mmap 的函数为 uio_mmap。至此,UIO 就可以让 PMD 驱动程序在用户态应用层访问设备的大部分资源了。
  • 应用层 UIO 初始化。同时,DPDK 还需要把 PCI 设备的 BAR 映射到应用层。
    在 pci_uio_map_resource 函数中会调用 pci_uio_map_resource_by_index 做资源映射。
  • 在 PMD 驱动程序中,DPDK 应用程序,会调用 rte_eth_rx_burst 读取数据报文。如果网卡接收 Buffer 的描述符表示已经完成一个报文的接收(e.g. 有 E1000_RXD_STAT_DD 标志),则 rte_mbuf_raw_alloc 一个 mbuf 进行处理。
  • 对应 RTC 模型的 DPDK 应用程序来说,就是不断的调用 rte_eth_rx_burst 去询问网卡是否有新的报文。如果有,就取走所有的报文或达到参数 nb_pkts 的上限。然后进行报文处理,处理完毕,再次循环。

uio_pci_generic

uio_pci_generic是内核原生的一种uio驱动,该驱动提供了uio功能,直接使用如下命令加载:

sudo modprobe uio_pci_generic

uio_pci_generic 和 igb_uio对比

  • uio_pci_generic 是不支持VF设备创建的, igb_uio 支持
    igb_uio可以用于宿主机上来创建VF设备。适用性比内核原生的uio_pci_generic更强一些,
  • igb_uio.ko是由 dpdk 代码库编译出来的,uio_pci_generic 是原生的,内核自带的。
sudo modprobe uio
sudo insmod kmod/igb_uio.ko

vfio-pci

在这里插入图片描述

从DPDK release 1.7开始,DPDK对VFIO进行了支持,因此VFIO Driver成了新的可选项:

sudo modprobe vfio-pci

特别注意:
对于使用VFIO驱动来使用DPDK的场景,必须保证:
1.硬件上支持支持VT-x、VT-d,BIOS中需要打开相关特性
2.对于物理机的内核中需要支持IOMMU特性(在启动参数添加 iommu=pt, intel_iommu=on)

  • 绑定vfio-pci 出错
    在这里插入图片描述

Bifurcated Driver: 分叉驱动

在这里插入图片描述
使用分叉驱动程序的PMD与设备内核驱动程序共存。 在这种模式下,NIC由内核控制,而数据路径则由PMD直接在设备上执行。
注:使用分叉驱动程序的PMD不应从其内核驱动程序中解除绑定。

Mellanox Bifurcated DPDK PMD

在这里插入图片描述
在这里插入图片描述

参见:Mellanox Bifurcated DPDK PMD

对比

如果正在使用的PMD使用UIO或VFIO驱动程序,那么DPDK应用程序要使用的所有端口都必须在应用程序运行之前绑定到uio_pci_generic、igb_uio或vfio-pci模块。 对于此类PMD,Linux 控制下的任何网络端口都将被忽略,并且不能被应用程序使用。

uio + igb_uio/uio_pci_generic的局限

在这里插入图片描述

绑定与解绑定

在这里插入图片描述

# 查看
Network devices using DPDK-compatible driver
============================================
0000:82:00.0 '82599EB 10-GbE NIC' drv=uio_pci_generic unused=ixgbe
0000:82:00.1 '82599EB 10-GbE NIC' drv=uio_pci_generic unused=ixgbe

Network devices using kernel driver
===================================
0000:04:00.0 'I350 1-GbE NIC' if=em0  drv=igb unused=uio_pci_generic *Active*
0000:04:00.1 'I350 1-GbE NIC' if=eth1 drv=igb unused=uio_pci_generic
0000:04:00.2 'I350 1-GbE NIC' if=eth2 drv=igb unused=uio_pci_generic
0000:04:00.3 'I350 1-GbE NIC' if=eth3 drv=igb unused=uio_pci_generic

Other network devices
=====================

 # 绑定:
./usertools/dpdk-devbind.py --bind=uio_pci_generic 04:00.1

宿主机上使用dpdk

在物理机上使用DPDK,需要内核中加载DPDK PMD Driver,那么需要使用如下命令加载DPDK的驱动:

modprobe uio
insmod igb_uio
usertools/dpdk-devbind.py --bind=igb_uio bb:ss.f

注:这里我们也可以使用上面介绍过的其他类型的内核模块:uio_pci_generic 或者 vfio-pci 。

虚拟机中使用DPDK

对于支持SR-IOV的网卡来说,比如Intel的X710/XL710网卡,在虚拟化的环境中使用,网卡可以进行透传,本文以透传的方式来进行实践介绍,对于支持SR-IOV的网卡来说,它分为PF和VF模块,在宿主机中需要加载对应的PF Driver和VF Driver来驱动这两个子模块。

宿主机

在宿主机上可以直接使用Linux kernel官方的intel PF驱动,比如i40e,也可以使用DPDK专用的 PMD PF驱动
如果使用了DPDK PMD PF 驱动,那么这个宿主机网络的管理权就完全交给DPDK了。

  • 方案一:i40e驱动
rmmod i40e (To remove the i40e module)
insmod i40e.ko max_vfs=2,2 (To enable two Virtual Functions per port)

通过重新加载intel提供的i40e驱动,并指定max_vfs参数来创建VF功能,对于该网卡的VF功能内核默认使用的驱动为 i40evf,因此在使用dpdk之前,还需要在Host上将VF与i40evf驱动解绑,重新绑定到vfio-pci驱动上:

modprobe vfio-pci
usertools/dpdk-devbind.py --bind=vfio-pci  bb:ss.f

1> 此时该VF已经由vfio驱动接管,如果在宿主机上使用VFIO DPDK,那么此时就已经满足了条件;
2> 如果为了演示虚拟机中使用DPDK,此时不能启动DPDK去使用该VF,而需要在虚拟机中透传该设备来使用。

宿主机中需要使用vfio_pci这个内核模块来对需要分配给客户机的设备进行隐藏, 从而让宿主机和未被分配该设备的客户机都无法使用该设备, 达到隔离和安全使用的目的。而在客户机不需要使用该设备后, 让宿主机使用该设备, 则需要将其恢复到使用原本的驱动。

  • 方案二:DPDK PMD PF驱动
    需要内核启动参数中使能iommu=pt, intel_iommu=on,然后启动后加载DPDK驱动:
modprobe uio
insmod kmod/igb_uio.ko
usertools/dpdk-devbind.py --bind=igb_uio bb:ss.f
echo 2 > /sys/bus/pci/devices/0000\:bb\:ss.f/max_vfs (To enable two VFs on a specific PCI device)

虚机

对于虚拟机来说,透传过来的VFIO网卡对于虚拟机来说就相当于是一个常规的物理网卡,默认就会使用该物理网卡对应的驱动,比如i40e driver。
那么如果要在虚拟机中使用DPDK,就需要把虚拟网卡重新绑定到igb_uio驱动,这样就可以在虚拟机中使用DPDK了。实际上操作还是与宿主机中一样:

modprobe uio
insmod kmod/igb_uio.ko
usertools/dpdk-devbind.py --bind=igb_uio bb:ss.f

参考

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

DPDK的PMD(uio/igb_uio/vfio-pci/uio_pci_generic) 的相关文章

  • dpdk无锁队列

    这篇博客是从网上博客整理摘抄而来 xff0c 具体参考的博客内容在文末给出 Linux无锁队列 kfifo概述 Linux内核中有一个先进先出的数据结构 xff0c 采用环形队列的数据结构来实现 xff0c 提供一个无边界的字节流服务 最重
  • OVS+DPDK

    DPDK简介 DPDK是X86平台报文快速处理的库和驱动的集合 xff0c 不是网络协议栈 xff0c 不提供二层 xff0c 三层转发功能 xff0c 不具备防火墙ACL功能 xff0c 但通过DPDK可以轻松的开发出上述功能 DPDK的
  • 万亿级KV存储架构与实践

    一 KV 存储发展历程 我们第一代的分布式 KV 存储如下图左侧的架构所示 相信很多公司都经历过这个阶段 在客户端内做一致性哈希 在后端部署很多的 Memcached 实例 这样就实现了最基本的 KV 存储分布式设计 但这样的设计存在很明显
  • 网络性能测试工具:iperf3

    一 iperf3简介 iperf3是一个网络性能测试工具 iperf3下载地址 iperf可以测试TCP和UDP带宽质量 iperf可以测量最大TCP带宽 具有多种参数和UDP特性 iperf可以报告带宽 延迟抖动和数据包丢失 iperf3
  • Linux HugePage

    1 闲聊 有一段时间 数据库上出现过CPU消耗非常高的问题 最后分析到了Linux HugePage 发现自己对这一块都没什么了解 于是做了 些了解 Linux 下的大页分为两种类型 标准大页 Huge Pages 和透明大页 Transp
  • docker存储管理及实例

    一 Docker存储概念 1 容器本地存储与Docke存储驱动 容器本地存储 每个容器都被自动分配了内部存储 即容器本地存储 采用的是联合文件系统 通过存储驱动进行管理 存储驱动 控制镜像和容器在 docker 主机上的存储和管理方式 容器
  • openssl生成椭圆曲线的私钥是如何做到每次不同的?

    目录 例子 排查 随机算法 小结 例子 生成一个私钥只需要3步 1 获得指定曲线的group 如比特币的secp256k1 2 group和key绑定 3 用key来生成私钥 先上一段代码例子 key1 EC KEY new if key1
  • 杂项记录

    2019 07 14 查看一些基础的信息 比如CPU 逻辑核等系你 查看某个网卡在哪个numa节点上https blog csdn net jpmsdn article details 84561294 DPDK最大支持核数 128 在rt
  • virtio代码分析(一)-qemu部分

    virtio内容众多 代码分布于qemu linux dpdk等中 而且分为frontend和backend 可以运行于userspace也可以运行于kernelspace 极其难以理解 不看代码只看原理性文档往往流于表面 只有真正看懂了代
  • 软件和硬件数据交互接口的的演进

    编者按AMD Kria SOM及KV260视觉入门套件介绍 电子发烧友在线研讨会 软件和硬件 既相互依存又需要某种程度上的相互独立 通过软件和硬件之间的接口把两者连接在一起 软硬件接口 有很多含义 比如指令集是CPU软件和硬件之间的接口 比
  • trex-bird使用过程解析

    trex bird原理 TRex Bird架构图 trex 结合bird服务是采用linux上的veth及网络命名空间的技术 bird运行在trex a bird ns 网络namespace里 创建veth虚接口对bird 0 0 T和b
  • dpdk+ovs安装和编译(一)

    绑定前网卡驱动 root localhost ethtool i enp5s0 driver hinic version firmware version expansion rom version bus info 0000 05 00
  • TCP参数参数调优

    前言 TCP 性能的提升不仅考察 TCP 的理论知识 还考察了对于操心系统提供的内核参数的理解与应用 TCP 协议是由操作系统实现 所以操作系统提供了不少调节 TCP 的参数 如何正确有效的使用这些参数 来提高 TCP 性能是一个不那么简单
  • ARP协议

    一 ARP概述 如果要在TCP IP协议栈中选择一个 最不安全的协议 那我会毫不犹豫把票投给ARP协议 我们经常听到的这些术语 包括 网络扫描 内网渗透 中间人拦截 局域网流控 流量欺骗 基本都跟ARP脱不了干系 大量的安全工具 例如大名鼎
  • DPDK — 安装部署

    1 基础环境 1 1 硬件配置 1 2 操作系统要求 2 测试环境编译测试过程 2 1 升级GCC版本至GCC 7 3 0 步骤1 升级GCC依赖包设置 编译安装gmp cd home tar xvf home gmp 6 1 2 tar
  • TCP/IP协议:传输层之UDP

    一 UDP用户数据报协议 它是一个无连接的 面向数据报的协议 它不提供可靠性但传输速度比TCP要快 UDP数据报中的 UDP长度 为两个字节 所以我们要发送的UDP数据最多支持65507大约68K的数据 超过该大小的话需要自己来分割发送 使
  • 查看linux中的TCP连接数

    一 查看哪些IP连接本机 netstat an 二 查看TCP连接数 1 统计80端口连接数 netstat nat grep i 80 wc l 2 统计httpd协议连接数 ps ef grep httpd wc l 3 统计已连接上的
  • DPDK RX/TX 回调示例应用程序中没有流量出现

    我是DPDK领域的新生 我从 DPDK 主页给出的示例应用程序开始 我被这个例子困住了 DPDK RX TX 回调示例应用程序 https doc dpdk org guides sample app ug rxtx callbacks h
  • DPDK“端口数必须为偶数”一台以太网设备

    我正在尝试从 DPDK 源代码运行骨架示例 但每当我尝试在 make 过程后构建代码时 我都会收到一条错误消息 端口数必须为偶数 但是当我尝试查看以太网设备列表时我只能看到一台设备 我在 vmware 工作站环境下的 Ubuntu 中运行框
  • 您可以以非 root 用户身份在非特权容器中运行 DPDK 吗?

    我正在尝试在非特权 Docker 容器中运行 DPDK 虽然我可以限制容器的权限并将容器指定为非特权容器 但我仍然需要以 root 身份运行 dpdk 应用程序 例如 testpmd 我还可以以非 root 身份运行容器并使用 sudo 启

随机推荐

  • EduCoder Java程序设计---Java面向对象(第八章) - 文件类答案

    第1关 创建文件 package step1 import java io File import java io FileFilter import java io IOException import java util Scanner
  • k8s基础11——安全控制之RBAC用户授权、RBAC用户组授权、SA程序授权

    文章目录 一 K8s安全框架 1 1 鉴权 1 1 1 HTTPS证书认证 1 1 2 HTTP Token认证 1 2 授权 1 3 准入控制 1 4 集群四大角色 二 RBAC给用户授权 TLS 2 1 签发客户端证书 2 2 生成ku
  • 使用Java的File类实现目录拷贝

    目录 准备工作 Case Analysis 代码实现 总结 准备工作 首先 我们来熟悉下File类 在 Java 中 File 类是 java io 包中唯一代表磁盘文件本身的对象 也就是说 如果希望在程序中操作文件和目录 则都可以通过 F
  • otsu算法_OTSU算法详解

    OTSU是阈值分割中一种常用的算法 它可以根据图像自动生成最佳分割阈值 OTSU的核心思想是类间方差最大化 OTSU算法详解 令 表示一幅大小为 像素的数字图像中的 个不同的灰度级 表示灰度级为 的像素数 图像中的像素总数为 像素的灰度级为
  • VS2017序列号

    趁着这两天微软发布了Visual Studio 2017 安装体验了这个史上最强IDE最新版 分享一下自己的安装过程 下载地址点击这里 该版本堪称史上最大IDE 随便勾了几个选项 就要占用几十个GB的安装空间 最后果断选择了最小安装包 只要
  • uniapp中单选按钮的实现

    标签说明 radio group 单项选择器 内部由多个
  • Java核心技术卷 学习Day02

    java学习 复习 本文主要参照 Java核心技术卷 作为学习对象 第四章 对象与类 1 类 面向对象程序设计OOP 类 封装实例字段 方法 类 gt 继承 is a 依赖 uses a 聚合 has a gt 类 2 预定义类 Math
  • JAVA---抽象类和接口基础知识详解(及两者异同点)

    在本篇博客中将介绍JAVA里抽象类和接口的基础知识以及两者的异同点 在有继承和多态的基础知识上学习会更好 目录 抽象类基础知识 抽象类的定义 创建等基础 抽象类的几点说明 一 为何使用抽象方法 抽象类的几点说明 二 接口基础知识 接口的定义
  • 【Zotero高效知识管理】(1)Zotero介绍

    Zotero高效知识管理 专栏其他文章 Zotero文献管理软件的系统性教程 包括安装 全面的配置 基于众多插件的文献导入 管理 引用 笔记方法 Zotero高效知识管理 2 Zotero的安装 百度云存储配置及常用插件安装 Zotero高
  • jsp调用controller方法_SpringMVC五大核心组件及调用过程

    Spring Web MVC 五大核心组件 DispatcherServlet 控制器入口 负责分发请求 HandlerMapping 负责根据请求 找到对应的控制器 Controller 真正处理请求的控制器 ModelAndView 封
  • 用于光栅仿真的非偏振光–实例讨论

    摘要 像光栅这样的光学设备对光的偏振比较敏感 因此 在仿真中适当考虑光的偏振非常重要 在实际中 光栅有时会以非偏振光作为输入 作为两个正交偏振态的平均值 我们为您展示了如何在VirtualLab Fusion中建模这种用于光栅仿真的非偏振光
  • C语言《文件操作》事无巨细,保姆级介绍,通俗易懂

    目录 1 文件名与文件分类 2 文件操作使用 2 1文件的打开与关闭 3 文件操作函数 3 1其他文件函数 1 fseek 2 ftell 3 rewind 4 文件结束的判定 4 1被错误使用的 feof 4 2文件结束的正确判断 5 文
  • negix安装部署

    1 从nginx官网下载Nginx wget http nginx org download nginx 1 8 1 tar gz 2 解压Nginx tar zxvf nginx 1 8 1 tar gz 3 初始化配置 configur
  • OpenCV(3.4.1) Error: Assertion failed (scn == 3

    错误 OpenCV 3 4 1 Error Assertion failed scn 3 scn 4 in cv cvtColor file D Build OpenCV opencv 3 4 1 modules imgproc src c
  • vi的一些操作

    1 u可撤销操作 2 yy复制当前行 3 p粘贴复制的行 4 dd删除一行 5 xxx可以定位xxx所在位置 6 n或ngg或nG可以跳转到第n行 以下设置是临时的 只在当前vi中生效 但可将其添加在配置文件 etc virc中使每次按文件
  • STM32CubeMX的使用教程

    STM32 关于STM32CubeMX的使用 打开Cube 点击File New Project 搜索芯片型号这边选择的是STM32L071CB系列上面菜单Docs Resources可以下载数据手册程序手册等 点击Start Projec
  • DEBUG:only Tensors of floating point dtype can require gradients

    DEBUG only Tensors of floating point dtype can require gradients 解决 x V t arange 2 4 float requires grad True
  • 4_hytrix_信号量_线程池

    文章目录 Hystrix 核心特性和原理 使用 单独使用 整合 Feign 整合RestTemplate 信号量与线程隔离 线程池隔离 信号量隔离 常用配置 hystrix 使用dashboard Hystrix 核心特性和原理 熔断 连续
  • C strtok strtok_s 函数说明 按分隔符分解字符串

    1 说明 1 1 函数签名如下 char strtok char str const char delimiters 1 str 要被分解成一组小字符串的字符串 2 delimiters 包含分隔符的 C 字符串 1 2 返回值 该函数返回
  • DPDK的PMD(uio/igb_uio/vfio-pci/uio_pci_generic)

    目录 linux收包的方式 中断对性能的影响有多大 轮询对性能的提升有多大 PMD 介绍 收包对比 内核收包的弊端 DPDK 收包的优点 uio igb uio uio pci generic vfio pci igb uio IGB UI