DPDK实践之(1)dpdk基础使用

news2024/12/22 14:34:51

DPDK实践之(1)dpdk基础使用


Author: Once Day Date: 2024年5月19日

一位热衷于Linux学习和开发的菜鸟,试图谱写一场冒险之旅,也许终点只是一场白日梦…

漫漫长路,有人对你微笑过嘛…

全系列文档可参考专栏:Linux基础知识_Once-Day的博客-CSDN博客

参考文章:

  • DPDK总结(网卡初始化)_rte_eth_dev_count_hz5034的博客-CSDN博客
  • DPDK之网卡收包流程 (qq.com)
  • Git DPDK资料下载
  • DPDK download
  • Getting Started Guide for Linux — documentation (dpdk.org)
  • Sample Applications User Guides — documentation (dpdk.org)

文章目录

  • DPDK实践之(1)dpdk基础使用
        • 1. 概述
          • 1.1 linux编译方式
          • 1.2 运行系统要求
          • 1.3 二级进程支持
        • 2. 源码编译
          • 2.1 编译方式
          • 2.2 编译步骤
        • 3. 运行dpdk基础程序
          • 3.1 Linux用户空间驱动
          • 3.2 dpdk程序运行标准步骤
          • 3.3 运行helloworld程序
          • 3.4 DPDK程序支持valgrind
        • 4. DPDK EAL参数
          • 4.1 CPU核心相关参数介绍
          • 4.2 网卡相关参数
          • 4.3 内存相关参数
          • 4.4 debug相关参数
          • 4.5 杂项选项
          • 4.6 Linux相关参数
        • 5. 附录
          • 5.1 DPDK运行CPU
          • 5.2 DPDK运行内存
          • 5.3 dpdk遥测功能

1. 概述

DPDK(Data Plane Development Kit)是一个由 Intel 开发并开源的软件库和驱动集合,用于在 commodity hardware(通用硬件)上进行快速封包处理。DPDK 可以极大提高数据包处理速度和吞吐量,使得网络应用能够高效地在 CPU 上运行,而无需依赖昂贵的专有硬件或专门的网络处理设备。

DPDK 的主要组成部分包括:

  1. Core Libraries:提供了一组用于处理数据包的核心库,包括内存、队列、缓冲池、端口和流量管理等功能。

  2. Poll Mode Drivers (PMDs):这些是为各种网络接口卡(NICs)编写的轮询模式驱动程序,可以绕过内核,直接在用户空间处理数据包。

  3. Additional Libraries:除了核心库和 PMDs,DPDK 还提供了一些附加的库,用于实现更高级的网络功能,如安全、流量管理和服务质量(QoS)等。

DPDK 也支持各种类型的处理器和操作系统,包括 Linux、FreeBSD 和 Windows,可以在 x86、Power 和 ARM 等架构上运行。

DPDK 官网文档地址是:http://www.dpdk.org/doc。您可以在此找到如何安装和使用 DPDK 的详细指南,以及各种参考文档和教程。

1.1 linux编译方式

对于大多数平台,使用基本的DPDK功能不需要特殊的BIOS设置。在x86上可能有一些BIOS设置先决条件:

  1. HPET计时器:如果你的应用程序需要使用高精度事件计时器(HPET),可能需要在BIOS中启用此功能。
  2. 功率管理:某些DPDK应用程序可能会受益于更精细的功率管理。例如,可以在BIOS中启用或禁用CPU的某些节能特性。
  3. 小数据包性能:对于一些需要处理大量小数据包的应用,可能需要在BIOS中调整某些设置以优化性能。例如,可能需要禁用CPU的某些节能特性,或者更改内存访问策略。

对于编译期,需要支持C11标准(包含atomic实现),以及一些配套的编译工具(gcc/clang/pkg-config/pkgconf等等)。以下是在不同的Linux发行版中安装这些开发工具的命令:

对于RHEL/Fedora系统:

sudo dnf groupinstall "Development Tools"

对于Ubuntu/Debian系统:

sudo apt update
sudo apt install build-essential

对于Alpine Linux:

apk add alpine-sdk bsd-compat-headers

pkg-config是一个脚本,它的主要目的是帮助你在编译过程中添加正确的编译器和链接器的选项。比如,如果你的程序需要一个库,需要知道这个库的头文件和库文件的位置。pkg-config可以帮你查询这些信息。

在Debian或Ubuntu等基于Debian的系统中,可以使用以下命令来安装pkg-config

sudo apt update
sudo apt install pkg-config

然后,你可以使用pkg-config命令来查询库的信息。例如,下面的命令可以查询libpng库的版本信息:

pkg-config --modversion libpng

pkgconfpkg-config的一个替代品,提供了相似的功能,并且有一些额外的改进。例如,pkgconf可以更好地处理库之间的依赖关系。

在Debian或Ubuntu等基于Debian的系统中,你可以使用以下命令来安装pkgconf

sudo apt update
sudo apt install pkgconf

然后,你可以像使用pkg-config一样使用pkgconf命令。

此外也需要以下依赖工具:

  1. Python 3.6 or later.
  2. Meson (version 0.53.2+) and ninja。Meson是一个开源的构建系统,旨在提供一个高效、用户友好的构建环境。Ninja是一个小型的构建系统,专注于速度,常常被用作Meson和其他构建系统(如CMake)的后端。
  3. pyelftools (version 0.22+)。pyelftools是一个Python库,用于解析和操作ELF (Executable and Linkable Format) 和 DWARF (Debug With Arbitrary Record Format) 格式的文件。这些格式被广泛用于可执行文件、目标文件、共享库和核心转储。
  4. Library for handling NUMA (Non Uniform Memory Access). libnuma-dev in Debian/Ubuntu。

一些工具和库是可选的,可以用来增强DPDK的功能或者使其能支持更多的硬件特性。

  • Intel® C++ Compiler (icc):这是Intel公司的C++编译器,可以充分利用Intel处理器的特性来优化代码。你可以在Intel官网找到安装指南和文档。在安装icc时,可能需要安装一些额外的库。

  • IBM® Advance ToolChain for Powerlinux:这是一个开源的开发工具集和运行时库,可以让用户在Linux系统上充分利用IBM最新的POWER硬件特性。你可以在IBM官网找到安装文档。

对于DPDK的一些组件,如库和poll-mode drivers (PMDs),可能需要额外的依赖。在构建DPDK时,这些依赖会被自动检测,并且会相应地启用或禁用相关的组件。

在所有情况下,都需要相应的库开发包(-devel或-dev)来构建DPDK组件。

例如,这些额外的依赖包括:

  • libarchive:一些单元测试使用tar获取它们的资源。
  • libelf:编译和使用bpf库。

对于每个poll-mode driver,其额外的依赖可以在相关的DPDK指南文档中找到:

  • Network Interface Controller Drivers — documentation (dpdk.org)
1.2 运行系统要求

参考文档:2. System Requirements — Data Plane Development Kit 24.03.0 documentation (dpdk.org)

下面是运行DPDK应用的基本系统需求:

  • Kernel version >= 4.14,Linux系统内核版本至少4.14之上。
  • glibc >= 2.7 (for features related to cpuset),Glibc版本至少在2.7之上。
  • Linux内核配置要求HUGETLBFS、PROC_PAGE_MONITOR support。
  • 如果HPET使能,则Linux内核配置要求HPET和HPET_MMAP也使能,可见High Precision Event Timer (HPET) Functionality。

Hugepages是一个在内核级别支持的特性,它可以使系统使用大于默认的4KB的内存页大小。使用Hugepages可以增加性能,因为需要的页数更少,因此需要更少的Translation Lookaside Buffers (TLBs)。TLB是一种高速的地址翻译缓存,它能减少从虚拟页地址到物理页地址的转换时间。如果不使用Hugepages,标准的4KB页大小会导致高TLB miss比率,进而降低性能。

在Linux系统中,可以通过下面的步骤启用和配置Hugepages:

  1. 检查内核支持:首先,需要确认Linux内核支持Hugepages。可以通过查看/proc/meminfo文件来确认这一点。在这个文件中,如果看到像HugePages_TotalHugePages_FreeHugepagesize这样的行,那么内核支持Hugepages。

  2. 配置Hugepages:可以通过sysctl命令或直接修改/etc/sysctl.conf文件来配置Hugepages的数量。例如,如果想设置Hugepages的数量为1024,可以将下面的行添加到/etc/sysctl.conf文件中:

    vm.nr_hugepages = 1024
    

    然后,可以运行sudo sysctl -p命令来应用这个更改。

  3. 挂载Hugepages文件系统:最后需要挂载一个Hugepages文件系统。可以通过mount命令来完成这个操作,如下:

    sudo mkdir -p /mnt/huge
    sudo mount -t hugetlbfs nodev /mnt/huge
    

    也可以将上面的行添加到/etc/fstab文件中,以便在系统启动时自动挂载Hugepages文件系统。

在运行时以及启动时预留hugepages。在许多情况下,预留hugepages可以优化高性能计算和网络应用的性能。

  1. 在运行时预留hugepages:可以通过向 /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages 文件写入需要的hugepages数量来在系统运行时预留hugepages。这对于单节点系统来说很简单。在多NUMA系统中,可以如下为NUMA节点单独预留hugepages。

    # 预留1024 * 2 MB的大页内存
    echo 1024 > /sys/devices/system/node/nodeX/hugepages/hugepages-2048kB/nr_hugepages
    
  2. 在启动时预留hugepages:在某些情况下,可能需要在系统启动时预留hugepages。这可以通过在内核命令行中添加参数来完成。例如,对于2MB的页,可以使用 hugepages=1024 参数。对于1GB的页,需要显式指定大小,如:

    default_hugepagesz=1G hugepagesz=1G hugepages=4
    

    一些内核不允许在运行时收集1G大小的内存页,因此需要在启动时预留,此时另外一个好处是内存物理地址也能更加连续。

  3. DPDK Hugepages管理工具:DPDK提供了一个工具 dpdk-hugepages.py,可以用来管理hugepages。

  4. Hugepages大小的支持:支持的hugepages大小取决于CPU的架构。在Intel架构中,如果CPU标志中存在 pse,则支持2MB的hugepages;如果存在 pdpe1gb,则支持1GB的hugepages。在IBM Power架构中,支持的hugepages大小为16MB和16GB。

  5. 64位应用的建议:对于64位应用,如果平台支持,推荐使用1GB的hugepages。

  6. NUMA系统中的分配:在双插槽NUMA系统中,启动时预留的hugepages数量通常在两个插槽之间平均分配(假设两个插槽上都有足够的内存)。

对于更多的内核选项,可以在Linux源代码树的 Documentation/admin-guide/kernel-parameters.txt 文件中查看。

1.3 二级进程支持

参考文档:2. System Requirements — Data Plane Development Kit 24.03.0 documentation (dpdk.org)

在DPDK(数据平面开发套件)中,二级进程(Secondary Process)是一种特殊的进程,它可以与主进程(Primary Process)共享某些资源,例如内存,队列等。在很多场景下,主进程负责初始化和启动一些服务,例如内存管理,设备管理等。然后,二级进程可以利用这些已经初始化的资源进行一些特定的任务。

这种设计使得在一个系统中可以运行多个进程,而不需要每个进程都进行一次完整的初始化。这样就可以降低启动时间,减少资源使用,提高整体性能。

在DPDK中,二级进程通常通过使用rte_eal_init函数的特定参数启动,这些参数使得二级进程能够找到并连接到主进程已经初始化的资源。

如果不需要二级进程支持,DPDK可以通过使用“in-memory”模式无需任何配置即可使用大页。如果需要二级进程支持,需要创建大页的挂载点在现代Linux发行版上,系统提供了一个默认的大页挂载点,位于/dev/hugepages。这个挂载点将使用上述内核参数设置的默认大页大小。

然而,为了使用默认以外的大页大小,需要手动为这些大页大小(例如1GB页)创建挂载点。为了使大小为1GB的大页可供DPDK使用,必须执行以下步骤:

mkdir /mnt/huge
mount -t hugetlbfs pagesize=1GB /mnt/huge

可以通过在/etc/fstab文件中添加以下行,使挂载点在重启后保持永久:

nodev /mnt/huge hugetlbfs pagesize=1GB 0 0
2. 源码编译
2.1 编译方式

有多种编译方式,这里以Linux平台X86本地编译为主,各种编译方式链接如下:

  • 3. Compiling the DPDK Target from Source — Data Plane Development Kit 23.11.0-rc1 documentation
  • 4. Cross compiling DPDK for aarch64 and aarch32 — Data Plane Development Kit 23.11.0-rc1 documentation
  • 5. Cross compiling DPDK for LoongArch — Data Plane Development Kit 23.11.0-rc1 documentation
  • 6. Cross compiling DPDK for RISC-V — Data Plane Development Kit 23.11.0-rc1 documentation
2.2 编译步骤

首先在官网下载源码文件(也可以在gitlab下载),选择合适的版本,然后进行解压:

onceday@book2023:~/dpdk-compile$ tar -xJf dpdk-22.11.3.tar.xz 
onceday@book2023:~/dpdk-compile$ cd dpdk-stable-22.11.3/

以下是这些目录更详细的解释:

  • doc目录,包含了DPDK的官方文档,如安装指南、程序员手册、API文档等。
  • license 目录,包含了DPDK的许可证信息。
  • lib目录,包含了构成DPDK的各种库的源代码,例如内存管理、缓冲池、队列、以太网控制器等。
  • drivers目录,包含了DPDK的轮询模式驱动程序的源代码,这些驱动程序主要用于网络接口卡。
  • app目录,包含了DPDK的应用程序的源代码,这些应用程序主要用于自动测试DPDK的各种功能。
  • examples目录,包含了一些DPDK应用程序的示例源代码,这些示例可以帮助开发者更好地理解和使用DPDK。
  • configbuildtools目录,包含了一些与构建和配置DPDK相关的脚本和配置文件。
  • usertools目录,包含了一些脚本,这些脚本可以帮助DPDK的最终用户更方便地使用DPDK应用程序。
  • devtools目录,包含了一些脚本,这些脚本主要供DPDK的开发者在开发过程中使用。
  • kernel目录,包含了一些内核模块的源代码,这些内核模块在某些操作系统上是必需的,例如Linux。

要配置DPDK构建,可以使用:

meson setup <options> build

其中,“build”是所需的输出构建目录,<options>可以为空或是meson或DPDK特定的构建选项之一。

配置好之后,要构建并安装DPDK到系统中,使用:

cd build
ninja
sudo meson install
sudo ldconfig

上面的最后两个命令通常需要以root身份运行,meson install步骤将构建的对象复制到最终的系统范围的位置,最后一步使动态加载器ld.so更新其缓存以考虑新的对象。

在某些Linux发行版中,例如Fedora或Redhat,/usr/local中的路径不在加载器的默认路径中。因此,在这些发行版上,应在运行ldconfig之前将/usr/local/lib/usr/local/lib64添加到/etc/ld.so.conf.d/目录中的一个文件里。你可以通过以下命令来做到这一点:

echo "/usr/local/lib" | sudo tee /etc/ld.so.conf.d/local_lib.conf
echo "/usr/local/lib64" | sudo tee -a /etc/ld.so.conf.d/local_lib.conf
sudo ldconfig

这样,加载器就可以在/usr/local/lib/usr/local/lib64中查找动态链接库了。

3. 运行dpdk基础程序
3.1 Linux用户空间驱动

参考文档:7. Linux Drivers — Data Plane Development Kit 24.03.0 documentation (dpdk.org)

DPDK 支持多种网卡驱动,包括 Intel IXGBE、Intel I40E、Intel ICE、Mellanox MLX4、Mellanox MLX5、Cisco enic 等。DPDK使用 UIO (Userspace I/O) 驱动或 VFIO (Virtual Function I/O) 驱动来实现用户态驱动,绕过内核网络协议栈,以提高数据包处理性能。

  • UIO 驱动包括 igb_uiouio_pci_generic,它们是内核模块,用于将网卡设备绑定到用户空间。
  • VFIO 驱动是一种更新的用户态驱动方式,它利用 IOMMU 实现设备直接分配给用户空间,提供更好的性能和安全性。

使用 dpdk-devbind.py 构建 DPDK 驱动环境:

  • dpdk-devbind.py 是 DPDK 提供的一个工具,用于管理网卡设备的驱动绑定。
  • 首先,确保已经加载了所需的内核模块,如 uioigb_uiovfio-pci
  • 使用 dpdk-devbind.py --status 命令查看当前系统中的网卡设备及其绑定的驱动。
  • 使用 dpdk-devbind.py --bind 命令将网卡设备绑定到 DPDK 支持的用户态驱动,例如:
    sudo dpdk-devbind.py --bind=uio_pci_generic eth0
    
    这将把 eth0 网卡绑定到 uio_pci_generic 驱动。
  • 如果需要将网卡设备恢复到内核驱动,可以使用 --unbind 选项:
    sudo dpdk-devbind.py --unbind eth0
    
  • 绑定完成后,可以再次使用 dpdk-devbind.py --status 命令确认网卡设备已经成功绑定到了目标驱动。

在使用 DPDK 时,绑定的网卡设备将无法被内核网络协议栈使用,因此在配置时需要谨慎选择要绑定的网卡设备,以免影响系统的正常网络功能

下面是一台虚拟云服务器的驱动查询情况:

ubuntu->build:$ sudo dpdk-devbind.py --status

Network devices using kernel driver
===================================
0000:00:05.0 'Virtio network device 1000' if=eth0 drv=virtio-pci unused=vfio-pci *Active*

eth0是一个虚拟接口,驱动是virtio-pci,可以更换为(危险操作)vfio-pci,然后dpdk就可以使用该接口。但是这里不建议这么操作,除非在本地设备上创建虚拟机完成这个操作。

一般的家用PC网卡驱动,dpdk都不支持用户空间驱动,因此后面用dpdk自行创建的虚拟接口完成测试,如下:

(1) TAP (Terminal Access Point) 设备是一种虚拟网络接口,模拟了一个以太网设备,可以与物理网络设备类似地进行数据包的发送和接收

  • 在 DPDK 中,可以使用 net_tap PMD (Poll Mode Driver) 创建 TAP 设备。通过 --vdev 参数指定 net_tap 设备,并提供相关的配置选项,例如:

    sudo testpmd -c 0x3 -n 4 --vdev 'net_tap0,iface=tap0' -- -i
    

    这个命令会创建一个名为 net_tap0 的虚拟接口,并将其与 tap0 这个 TAP 设备关联。

  • TAP 设备创建后,可以像物理网卡一样进行配置,例如设置 IP 地址、子网掩码等

  • DPDK 应用程序可以通过 rte_eth_rx_burstrte_eth_tx_burst 等 API 函数来接收和发送 TAP 设备上的数据包。

  • TAP 设备的优点是配置简单,容易与现有的网络环境集成。它可以与其他虚拟化技术(如 QEMU、VirtualBox 等)配合使用,实现虚拟机与 DPDK 应用程序之间的网络通信。

(2) virtio 接口,virtio 是一种用于虚拟化环境的通用 I/O 框架,它提供了一组标准的接口和协议,用于在虚拟机和宿主机之间高效地传输数据

  • DPDK 支持使用 virtio-user 后端创建基于 virtio 的虚拟接口。通过 --vdev 参数指定 net_virtio_user 设备,并提供相关的配置选项,例如:
    sudo testpmd -c 0x3 -n 4 --vdev 'net_virtio_user0,path=/tmp/vhost-sock0' -- -i
    
    这个命令会创建一个名为 net_virtio_user0 的虚拟接口,并将其与 /tmp/vhost-sock0 这个 Unix 域套接字关联。
  • virtio 接口的数据传输是基于共享内存的,通过在虚拟机和宿主机之间共享内存区域来实现高效的数据传输
  • DPDK 应用程序可以通过 rte_eth_rx_burstrte_eth_tx_burst 等 API 函数来接收和发送 virtio 接口上的数据包。
  • virtio 接口的优点是性能高,可以利用虚拟化技术提供的硬件加速功能,如 SR-IOV、IOMMU 等,实现近乎裸金属的性能。
  • virtio 接口常用于 DPDK 应用程序与虚拟机的高性能网络通信场景,例如在 NFV (网络功能虚拟化)中,通过 virtio 接口将虚拟机中的网络流量高效地转发给 DPDK 应用程序进行处理。

TAP 设备配置简单,易于与现有网络环境集成,而 virtio 接口则提供了更高的性能,适用于对网络性能要求较高的场景

3.2 dpdk程序运行标准步骤

DPDK应用的启动通常涉及以下几个步骤:

  1. 环境设置:在运行DPDK应用之前,需要设置一些环境变量,例如,对Hugepages的配置。这可以通过在启动脚本中设置nr_hugepages参数来完成。

    echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
    
  2. 绑定驱动:DPDK应用需要直接访问网络设备。这需要将网络设备的驱动从常规的Linux网络驱动(例如e1000)更改为DPDK支持的用户空间驱动,如uio_pci_genericigb_uiovfio

    首先,加载适当的UIO模块,例如igb_uio

    sudo modprobe uio
    sudo insmod kmod/igb_uio.ko
    

    然后,找出要绑定到DPDK的网络设备的PCI地址。你可以使用lspci命令来查找,例如:

    lspci | grep Ethernet
    

    设备的PCI地址应该类似于01:00.002:00.0

    最后,使用dpdk-devbind.py工具将设备绑定到igb_uio驱动:

    sudo python3 usertools/dpdk-devbind.py --bind=igb_uio 01:00.0
    
  3. 启动应用:使用sudo启动应用时,将PCI设备的地址作为参数传递给应用。

    sudo ./build/l2fwd -l 0-3 -n 4 -- -q 8 -p 0x1
    
3.3 运行helloworld程序

默认的dpdk编译里没有包含helloworld这个示例程序,因此这里先添加helloworld编译选项,如下:

在dpdk源码界面输入以下命令:

sudo meson configure build -Dexamples=helloworld
cd build
sudo ninja

然后就可以在examples目录下面看到编译出来的可执行程序:

ubuntu->build:$ ll examples/
-rwxr-xr-x  1 root   root   32900088 May 19 17:12 dpdk-helloworld*

先尝试直接运行,会出现错误:

ubuntu->build:$ ./examples/dpdk-helloworld
EAL: Detected CPU lcores: 4
EAL: Detected NUMA nodes: 1
EAL: Detected static linkage of DPDK
EAL: Multi-process socket /run/user/1000/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'VA'
EAL: No free 2048 kB hugepages reported on node 0
EAL: FATAL: Cannot get hugepage information.
EAL: Cannot get hugepage information.
PANIC in main():
Cannot init EAL
6: [./examples/dpdk-helloworld(_start+0x25) [0x55b1030fcda5]]
5: [/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80) [0x7f818377ae40]]
4: [/lib/x86_64-linux-gnu/libc.so.6(+0x29d90) [0x7f818377ad90]]
3: [./examples/dpdk-helloworld(+0x1f130c) [0x55b1023e630c]]
2: [./examples/dpdk-helloworld(__rte_panic+0xcd) [0x55b102402293]]
1: [./examples/dpdk-helloworld(rte_dump_stack+0x32) [0x55b10329cab2]]
Aborted

这里提示没有找到可用的大页内存,所以使用3.2节里的方法来保留大页内存,如下(需要root权限):

onceday->~:# echo 128 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

然后使用管理员权限运行,如下:

ubuntu->build:$ sudo ./examples/dpdk-helloworld
EAL: Detected CPU lcores: 4
EAL: Detected NUMA nodes: 1
EAL: Detected static linkage of DPDK
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
EAL: VFIO support initialized
EAL: Probe PCI driver: net_virtio (1af4:1000) device: 0000:00:05.0 (socket 0)
eth_virtio_pci_init(): Failed to init PCI device
EAL: Requested device 0000:00:05.0 cannot be used
TELEMETRY: No legacy callbacks, legacy socket not created
hello from core 1
hello from core 2
hello from core 3
hello from core 0

可以看到,默认在所有核上运行一个线程,每个线程都输出一个hello,这就是dpdk的per-core处理,能够在每个核上绑定一个线程。此外,这里提示PCI驱动绑定失败,这是因为运行之前没有替换网卡驱动为DPDK支持的用户空间驱动。

3.4 DPDK程序支持valgrind

在X86上,会因为AVX512指令集导致valgrind支持异常,根据stack-overflow回答,需要关闭dpdk编译对avx512指令集的支持情况,可参考文档:gcc - Disabling all AVX512 extensions - Stack Overflow。

这个avx512指令集通过一个python脚本检测,直接修改代码即可(直接返回错误):

#buildtools/binutils-avx512-check.py
import subprocess
import sys
import tempfile

objdump, *cc = sys.argv[1:]
with tempfile.NamedTemporaryFile() as obj:
    # On Windows, the file is opened exclusively and is not writable.
    sys.exit(1) # 这里直接返回错误
    obj.close()
    # from https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90028
    gather_params = '0x8(,%ymm1,1),%ymm0{%k2}'
    src = '__asm__("vpgatherqq {}");'.format(gather_params).encode('utf-8')
    subprocess.run(cc + ['-c', '-xc', '-o', obj.name, '-'], input=src, check=True)
    asm = subprocess.run([objdump, '-d', '--no-show-raw-insn', obj.name],
                         stdout=subprocess.PIPE, check=True).stdout.decode('utf-8')
    if gather_params not in asm:
	    print('vpgatherqq displacement error with as')
	    sys.exit(1)

然后使用meson setup后,生成的rte_build_config.h文件里就不会包含相关的指令集,即:

#define RTE_COMPILE_TIME_CPUFLAGS RTE_CPUFLAG_SSE,RTE_CPUFLAG_SSE2,RTE_CPUFLAG_SSE3,RTE_CPUFLAG_SSSE3,RTE_CPUFLAG_SSE4_1,RTE_CPUFLAG_SSE4_2,RTE_CPUFLAG_AES,RTE_CPUFLAG_AVX,RTE_CPUFLAG_AVX2,RTE_CPUFLAG_PCLMULQDQ,RTE_CPUFLAG_RDRAND,RTE_CPUFLAG_RDSEED

使用valgrind来检测dpdk-helloworld的内存使用情况,如下:

ubuntu->build:$ sudo valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all --track-origins=yes ./examples/dpdk-helloworld
==2444979== Memcheck, a memory error detector
==2444979== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.
==2444979== Using Valgrind-3.23.0 and LibVEX; rerun with -h for copyright info
==2444979== Command: ./examples/dpdk-helloworld
==2444979== 
EAL: Detected CPU lcores: 4
EAL: Detected NUMA nodes: 1
EAL: Detected static linkage of DPDK
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
......(省略大量内容)......
==2444979== LEAK SUMMARY:
==2444979==    definitely lost: 0 bytes in 0 blocks
==2444979==    indirectly lost: 0 bytes in 0 blocks
==2444979==      possibly lost: 1,600 bytes in 5 blocks
==2444979==    still reachable: 43,254 bytes in 445 blocks
==2444979==         suppressed: 0 bytes in 0 blocks
==2444979== 
==2444979== For lists of detected and suppressed errors, rerun with: -s
==2444979== ERROR SUMMARY: 19 errors from 14 contexts (suppressed: 0 from 0)

从运行结果来看,有很多泄露地方,这是因为dpdk库并未考虑对一些持续存在的内存进行释放,而且由于申请了太多的虚拟地址,导致valgrind的执行结果较久,效率较低

如果想将valgrind完全用于dpdk,还需要进一步优化dpdk相关的函数,来减少这类误报和执行效率问题。

4. DPDK EAL参数

参考文档:9. EAL parameters — Data Plane Development Kit 24.03.0 documentation (dpdk.org):

4.1 CPU核心相关参数介绍

-c COREMASK/-l CORELIST,用于指定应用程序使用的逻辑核。COREMASK是一个十六进制位掩码,CORELIST是一个逗号分隔的逻辑核列表。例如,--lcores 0-3表示将逻辑核心0-3映射到物理核心0-3

--lcores <core map>,该参数用于将逻辑核心集合映射到物理CPU核心集合。参数格式为:

<lcores[@cpus]>[<,lcores[@cpus]>...]

其中,lcores表示逻辑核心列表,cpus表示物理CPU核心列表。多个映射关系可以用逗号",“分隔。在每个映射关系中,可以用括号”()“将lcores和cpus括起来表示一个组。连字符”-“用于指定连续的核心编号范围,逗号”,“用于分隔单个核心编号。如果一个组只有一个元素,可以省略括号。如果lcores和cpus的值相同,可以省略”@"符号。

例如,--lcores 0-3@(0-3),4@(4)表示将逻辑核心0-3映射到物理核心0-3,将逻辑核心4映射到物理核心4。

--main-lcore <core ID>,该参数用于指定主核心的ID。在DPDK应用程序中,通常会有一个主线程(main thread)用于执行初始化、配置和控制任务,而其他线程则用于处理数据包。–main-lcore参数就是用来指定运行主线程的核心ID。

-s <service core mask>,该参数用于设置服务核心的十六进制掩码。服务核心是DPDK应用程序中专门用于处理服务任务的核心,如定时器、警报等。这些任务通常与数据包处理无关,但是对于应用程序的正常运行非常重要。

4.2 网卡相关参数

-b, --block <[domain:]bus:devid.func>,该参数用于阻止EAL(Environment Abstraction Layer)使用指定的PCI设备。通过指定设备的域(domain)、总线(bus)、设备ID(devid)和功能(func),可以跳过对该设备的探测,从而防止EAL使用它。可以使用多个-b选项来阻止多个设备。

例如,"-b 0000:01:00.0"表示阻止EAL使用域0、总线1、设备ID为0、功能为0的PCI设备。

-a, --allow <[domain:]bus:devid.func>,该参数用于将指定的PCI设备添加到EAL的探测列表中。与-b选项类似,需要指定设备的域、总线、设备ID和功能。

例如,"-a 0000:02:00.0"表示将域0、总线2、设备ID为0、功能为0的PCI设备添加到EAL的探测列表中。

需要注意,-a选项不能与-b(阻止列表)选项同时使用

--vdev <device arguments>,该参数用于添加虚拟设备。虚拟设备是指不是物理存在的设备,而是由DPDK模拟的设备。–vdev参数的格式为<driver><id>[,key=val, ...],其中,driver是虚拟设备的驱动名称,id是设备的唯一标识符,key=val是可选的参数。

例如,--vdev 'net_pcap0,rx_pcap=input.pcap,tx_pcap=output.pcap表示添加一个名为net_pcap0的虚拟设备,该设备使用PCAP驱动,并指定了rx_pcap和tx_pcap两个参数,分别表示接收和发送数据包的PCAP文件。

-d <path to shared object or directory>,该参数用于加载外部驱动程序。可以指定单个共享对象文件的路径,也可以指定包含多个驱动程序共享对象的目录路径。可以使用多个-d选项来加载多个驱动程序。

例如,-d /usr/local/lib/dpdk/drivers表示加载/usr/local/lib/dpdk/drivers目录下的所有驱动程序。

--no-pci,该参数用于禁用PCI总线。使用该参数后,EAL将不会探测和使用任何PCI设备。

4.3 内存相关参数

-n <number of channels>,该参数用于设置内存通道的数量。在多通道内存系统中,可以通过增加通道数来提高内存带宽和性能。EAL将根据指定的通道数对内存进行初始化和分配。

例如,-n 4表示使用4个内存通道。

-r <number of ranks>,该参数用于设置内存条(rank)的数量。内存条是指物理内存模块,一个内存通道可以有多个内存条。EAL默认会自动检测内存条的数量,但也可以通过-r参数手动指定。

例如,-r 2表示每个内存通道有2个内存条。

-m <megabytes>,该参数用于指定在启动时预先分配的内存大小,单位为兆字节(MB)。EAL将在应用程序启动时一次性分配指定大小的内存,以避免运行时频繁的内存分配和释放操作,提高性能。

例如,-m 1024表示预先分配1024MB(即1GB)的内存。

--in-memory,该参数用于指定EAL完全在内存中运行,不创建任何共享数据结构。这意味着EAL不会使用共享内存、共享文件等跨进程通信的机制,而是将所有数据都保存在进程的内存空间中。使用该参数可以提高性能,但也会增加内存消耗。

需要注意的是,--in-memory参数隐含了--no-shconf(不创建共享配置)和--huge-unlink(如果适用,不创建大页面文件)参数的效果。

--iova-mode <pa|va>,该参数用于强制指定IOVA(I/O Virtual Address)模式。IOVA是用于进行DMA(直接内存访问)操作的虚拟地址空间。EAL支持两种IOVA模式:物理地址(pa)和虚拟地址(va)。

例如,--iova-mode pa表示强制使用物理地址作为IOVA。

--huge-worker-stack[=size],该参数用于从大页面内存中分配工作线程的栈空间。默认情况下,EAL使用系统的pthread栈大小作为工作线程的栈大小。使用--huge-worker-stack参数可以将栈分配在大页面内存中,以提高性能。可以通过可选的size参数指定栈的大小,单位为KB。

例如,--huge-worker-stack表示使用大页面内存分配工作线程栈,栈大小为默认的pthread栈大小。而"–huge-worker-stack=4096"表示使用大页面内存分配工作线程栈,栈大小为4MB。

4.4 debug相关参数

--no-shconf,该参数用于指定EAL不创建任何共享文件。这意味着EAL将不支持辅助进程(secondary process),因为辅助进程依赖于与主进程共享的配置文件和内存。使用该参数可以简化EAL的配置和管理,但也会限制应用程序的功能。

--no-huge,该参数用于指定EAL使用匿名内存而不是大页面(hugepages)。与--no-shconf参数类似,使用--no-huge参数也会导致EAL不支持辅助进程,因为辅助进程通常与主进程共享大页面内存。使用匿名内存可以简化内存管理,但也可能影响性能。

--log-level <type:val>,该参数用于为特定组件指定日志级别。可以多次使用该参数来设置不同组件的日志级别。参数格式为:--log-level <组件>:<级别>,其中,<组件>是EAL中的组件名称,如lib.eal表示EAL库;<级别>是日志级别,如debug表示调试级别。例如,--log-level lib.eal:debug表示将EAL库的日志级别设置为调试级别。

--trace=<regex-match>,该参数用于根据正则表达式匹配的跟踪名称启用跟踪功能。默认情况下,跟踪功能是禁用的,需要通过--trace参数显式启用。可以多次使用该参数,最多可以指定32个跟踪配置。

例如,--trace=eal表示启用EAL组件的全局跟踪配置,--trace=.*表示启用所有组件的全局跟踪配置。

--trace-dir=<directory path>,该参数用于指定跟踪输出的目录路径。默认情况下,跟踪输出文件会创建在用户的主目录中。可以通过--trace-dir参数指定其他目录。该参数只能指定一次。

例如,--trace-dir=/tmp表示将/tmp目录配置为跟踪输出目录。

--trace-bufsz=<val>,该参数用于指定每个线程的跟踪输出文件的最大大小。可以使用B、K、M等单位分别表示字节、千字节、兆字节。默认情况下,跟踪输出文件的大小为1MB。该参数只能指定一次。

例如,--trace-bufsz=2M表示将跟踪输出文件的最大大小配置为2MB。

--trace-mode=<o[verwrite] | d[iscard]>,该参数用于指定跟踪输出文件的更新模式。当文件大小达到最大限制时,可以选择覆盖(overwrite)或丢弃(discard)新的跟踪更新。默认模式为覆盖。该参数只能指定一次。

例如,“–trace-mode=d"或”–trace-mode=discard"表示当跟踪输出文件达到最大大小时,丢弃新的跟踪更新。

4.5 杂项选项

-h, --help,显示帮助信息,列出所有可用的 EAL (Environment Abstraction Layer) 参数。

-v,在应用程序启动时显示版本信息。这对于确认您正在运行的 DPDK 版本很有帮助。

--mbuf-pool-ops-name,指定 mbuf (内存缓冲区) 使用的池操作名称。DPDK 使用 mbuf 来管理数据包缓冲区,不同的池操作可能针对不同的使用场景进行了优化。

--telemetry,启用遥测功能(默认启用)。DPDK 的遥测功能可以收集运行时的性能指标和事件,帮助进行性能分析和优化。

--no-telemetry,禁用遥测功能。

--force-max-simd-bitwidth=<val>,指定处理器支持的最大 SIMD (Single Instruction, Multiple Data) 位宽。这将限制程序使用的向量指令集。例如:

  • --force-max-simd-bitwidth=512: 允许使用最大 512 位的 SIMD 指令,即 AVX-512。
  • --force-max-simd-bitwidth=64: 将 SIMD 位宽限制为 64 位,实际上禁用了所有向量化代码。
  • --force-max-simd-bitwidth=0: 禁用 SIMD 位宽限制。
4.6 Linux相关参数

--create-uio-dev,为绑定到 igb_uio 内核驱动程序的设备创建 /dev/uioX 文件。通常由 igb_uio 驱动程序自行完成。例如,如果有两个网卡绑定到了 igb_uio 驱动,那么会自动创建 /dev/uio0/dev/uio1 文件。

--vmware-tsc-map,使用 VMware TSC 映射而不是原生 RDTSC。在 VMware 虚拟机中运行 DPDK 应用时,使用该选项可以提高时间戳计数器的精确度。

--no-hpet,不使用高精度事件计时器(HPET)。在某些系统上,禁用 HPET 可能有助于提高性能。

--vfio-intr <legacy|msi|msix>,为绑定到 VFIO 内核驱动程序的设备使用指定的中断模式。例如,--vfio-intr msix 表示使用 MSI-X 中断模式,相比于旧的中断模式,它可以支持更多的中断向量。

--vfio-vf-token <uuid>, 为绑定到 VFIO 内核驱动程序的设备使用指定的 VF 令牌。这在使用 SR-IOV 虚拟功能时很有用,可以确保不同的 DPDK 进程使用不同的虚拟功能。

--file-prefix <prefix name>,为 DPDK 进程使用不同的共享数据文件前缀。这允许在不同前缀下运行多个独立的 DPDK 主/从进程。例如,--file-prefix foo 将创建以 foo 开头的共享数据文件,而不是默认的 rte 前缀。

--legacy-mem,使用传统的 DPDK 内存分配模式。在较新版本的 DPDK 中,默认使用更高效的内存分配方式。

--socket-mem <amounts of memory per socket>,预分配每个 socket 指定数量的内存。例如,--socket-mem 1024,2048 将在 socket 0 上分配 1GB 内存,在 socket 1 上分配 2GB 内存。

--socket-limit <amounts of memory per socket>,对每个 socket 的内存使用设置上限(仅限非传统内存模式)。例如,--socket-limit 2048,4096 将 socket 0 的内存使用限制为 2GB,socket 1 限制为 4GB。值为 0 表示对特定 socket 禁用限制。

--single-file-segments,在 hugetlbfs 中创建更少的文件(仅限非传统模式)。这有助于减少 hugetlbfs 中的文件数量,并提高性能。

--huge-dir <path to hugetlbfs directory>,使用指定的 hugetlbfs 目录,而不是自动检测的目录。例如,--huge-dir /mnt/huge2M 表示使用 /mnt/huge2M 作为 hugetlbfs 目录。

--huge-unlink[=existing|always|never],控制如何删除 hugepage 文件。默认行为是删除并重新创建现有的 hugepage 文件。--huge-unlink=always 表示总是删除 hugepage 文件。--huge-unlink=never 表示从不删除,而是重新映射,允许重用 hugepage。

--match-allocations,按照原始分配的方式将 hugepage 释放回系统。这有助于避免内存碎片问题。

--proc-type <primary|secondary|auto>,设置当前进程的类型。primary 表示主进程,secondary 表示从进程,auto 表示自动检测。

--base-virtaddr <address>,尝试为主 DPDK 进程的所有内存映射使用不同的起始地址。当从进程由于地址映射冲突而无法启动时,这个选项很有帮助。例如,--base-virtaddr 0x7f000000000 将起始虚拟地址设置为 0x7f000000000。

5. 附录
5.1 DPDK运行CPU

DPDK应用程序通过EAL(Environment Abstraction Layer)管理和配置逻辑核心。coremask (-c 0x0f)corelist (-l 0-3)参数用于指定应用程序使用的逻辑核,每个参数位对应一个逻辑核号。在应用程序初始化时,EAL会显示使用的逻辑核及其所在的物理CPU socket。了解逻辑核与物理CPU之间的映射关系,有助于优化NUMA架构下的性能。

DPDK应用程序采用轮询而非中断模式处理数据包,因此需要专门的worker逻辑核。除worker核外,EAL还使用一个master逻辑核做管理任务,master核通常与worker核分开,以免影响性能。

在高性能场景下,如OVS-DPDK,通常会将整个逻辑核专门绑定给DPDK使用,而不与其他程序共享,以最小化上下文切换开销,实现最优数据面性能。这种使用独占逻辑核的方式在生产中非常普遍。

5.2 DPDK运行内存

DPDK应用程序在启动时可以通过-m--socket-mem参数来指定使用的内存大小。如果没有显式传递这些参数,DPDK会自动使用与hugepage分配的内存大小相同的内存。

如果显式传递了-m--socket-mem参数,但请求的内存大小超过了预留的hugepage内存,应用程序会启动失败。另一方面,如果请求的内存小于预留的hugepage内存,尤其是使用-m选项时,应用程序也可能会失败。假设系统在socket 0socket 1上分别预留了1024个2MB的hugepage。如果用户请求128MB内存,这64个页面可能无法满足以下约束:

  • 内核可能只在socket 1上给应用程序分配hugepage内存。在这种情况下,如果应用程序尝试在socket 0上创建对象(如ring或memory pool),就会失败。

  • 这些页面可以位于物理内存中的任何位置,尽管DPDK EAL会尝试以连续块的方式分配内存,但这些页面可能不是连续的。在这种情况下,应用程序无法分配大的内存池。

为了避免上述问题,建议使用--socket-mem选项而不是-m选项。–socket-mem选项可用于为特定的socket请求指定数量的内存

  • 例如,--socket-mem=0,512表示仅为socket 1保留512MB内存。
  • 在四个socket的系统上,要在socket 0和socket 2上各分配1GB内存,可以使用参数--socket-mem=1024,0,1024。未显式引用的CPU socket(如本例中的socket 3)不会预留任何内存。

如果DPDK无法在每个socket上分配足够的内存,EAL初始化将失败。

5.3 dpdk遥测功能

DPDK 的遥测功能允许收集应用程序运行时的各种指标和事件,以便进行性能分析和优化。要使用遥测功能,需要执行以下步骤:

  1. 配置遥测,在应用程序启动时,DPDK 会自动启用遥测功能。可以通过环境变量或配置文件来调整遥测的行为,例如指定输出的目标(如文件或套接字)、采样频率等。

  2. 编写遥测点,在 DPDK 应用程序代码中,可以使用 DPDK 提供的 API 函数来记录遥测点。

    例如使用 rte_telemetry_register_callback() 函数注册一个回调函数,当特定的遥测事件发生时,该函数将被调用。

  3. 运行应用程序,启动 DPDK 应用程序,遥测功能将在后台收集指标和事件。

  4. 收集和分析遥测数据,DPDK 提供了工具来帮助收集和可视化遥测数据。例如,dpdk-telemetry-client 工具可以连接到正在运行的 DPDK 应用程序,并实时显示遥测指标。还可以将遥测数据导出到文件或其他工具进行进一步分析。







Alt

Once Day

也信美人终作土,不堪幽梦太匆匆......

如果这篇文章为您带来了帮助或启发,不妨点个赞👍和关注,再加上一个小小的收藏⭐!

(。◕‿◕。)感谢您的阅读与支持~~~

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

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

相关文章

C++:关联容器及综合运用:

关联容器和顺序容器有着根本的不同:关联容器中的元素是按关键字来保存和访问的,而顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的。关联容器因此相比与顺序容器支持高效的关键字查找和访问。 其底层数据结构&#xff1a;顺序关联容器 ->红黑树&#xff0c;插入…

Matlab-遗传算法

文章目录 遗传算法一、介绍二、遗传算法的思想1.试用范围2.案例2.1 算法思路2.2 代码实现 遗传算法 一、介绍 遗传算法是一个启发式算法&#xff0c;主要可以用于优化问题&#xff0c;下边将进行举例来进行初步了解。 举例: 从做菜说起&#xff0c;首先你是一个大厨&#xff…

Ubuntu22.04本地部署qwen模型、jupyterlab开发环境、LoRA微调全流程

前言 这段时间在自己的Win11系统上部署了chatGLM以及Qwen模型&#xff0c;进行对话、推理以及工具调用都没有问题&#xff0c;但是在尝试进行微调的时候发现好像并不能成功&#xff0c;因此花费了很大的力气&#xff0c;又分别在ubuntu桌面版、windows子系统WSL2 Ubuntu上部署…

leetcode-55 跳跃游戏

leetcode Problem: 55. 跳跃游戏 思路 假设我们是一个小人&#xff0c;从第一个下标开始&#xff0c;每次经过一个位置&#xff0c;我们就可以根据当前位置的数值nums[i]和位置下标i计算出该位置所能到达的后续位置的最大值rnums[i]i。而这个r之前的区域一定都是可以经过的。…

Point-to-Voxel Knowledge Distillation for LiDAR Semantic Segmentation论文阅读

1. 代码地址 GitHub - cardwing/Codes-for-PVKD: Point-to-Voxel Knowledge Distillation for LiDAR Semantic Segmentation (CVPR 2022) 2. 动机 本篇文章旨在将点云语义分割的复杂模型中的知识蒸馏到较轻量级的模型中。具体的实现方式为将原有的3D backbone网络的每一层进…

恶劣天候激光雷达点云模拟方法论文整理

恶劣天候点云模拟方法论文整理 模拟雨天点云&#xff1a;【AAAI2024】模拟雪天点云&#xff1a;【CVPR 2022 oral】模拟雾天点云&#xff1a;【ICCV2021】模拟点云恶劣天候的散射现象&#xff1a;【Arxiv 2021】模拟积水地面的水花飞溅点云&#xff1a;【RAL2022】 模拟雨天点云…

蓝桥杯Web开发【大赛大纲】15届

一、 组别 Web应用开发分为&#xff1a;大学组和职业院校组。 每位选手只能申请参加其中一个组别的竞赛。各个组别单独评奖。 研究生和本科生只能报大学组。 其它高职高专院校可自行选择报任意组别。 二. 竞赛赛程 省赛时长&#xff1a;4小时。 决赛时长&#xff1a;4小…

纹理映射技术在AI去衣中的艺术与科技融合

引言&#xff1a; 在数字图像处理的世界里&#xff0c;AI去衣技术正逐步揭开其神秘的面纱。这门技术结合了深度学习的智能算法与图形学的先进手段&#xff0c;以实现对图像中衣物的智能识别与处理。在这一过程中&#xff0c;纹理映射技术发挥着至关重要的作用。本篇博客将深入探…

【GESP试卷】2024年03月Scratch四级试卷

2024年GESP03月认证Scratch四级试卷 分数&#xff1a;100 题数&#xff1a;27 一、单选题(共15题&#xff0c;每题2分&#xff0c;共30分) 010203040506070809101112131415CDBBACBCDCDADBA 1、小杨的父母最近刚刚给他买了一块华为手表&#xff0c;他说手表上跑的是鸿蒙&…

【综合类型第 39 篇】《我的创作纪念日》成为创作者的第2048天

这是【综合类型第 39 篇】&#xff0c;如果觉得有用的话&#xff0c;欢迎关注专栏。 前言 无意间看了一眼CSDN的私信&#xff0c;提示我 Allen Su &#xff0c;不知不觉今天已经是你成为创作者的 第2048天 啦&#xff0c;为了纪念这一天&#xff0c;我们为您准备了一份专属小…

vue3 响应式基础(怎么改变界面值)

在开发中&#xff0c;我们需要在改变一个数据的同时&#xff0c;去改变页面的变化&#xff0c;那这个时候响应式声明用起来就比较方便 之前做安卓开发的时候&#xff0c;要改变页面&#xff0c;首先拿到页面的一个控件&#xff0c;再对控件进行赋值或者其他的操作来改变界面 1、…

孢子捕捉分析仪的工作原理

TH-BZ1孢子捕捉分析仪是一种专门用于捕捉和分析空气中飘浮的病原菌孢子的设备。它利用现代传感技术、图像识别技术和网络通信技术&#xff0c;通过设置在田间的设备&#xff0c;连续不断地抽吸周围空气&#xff0c;吸附空气中漂浮的病原菌孢子到特制的载玻带上。然后&#xff0…

基于Kafka的日志采集

目录 前言 架构图 资源列表 基础环境 关闭防护墙 关闭内核安全机制 修改主机名 添加hosts映射 一、部署elasticsearch 修改limit限制 部署elasticsearch 修改配置文件 启动 二、部署filebeat 部署filebeat 添加配置文件 启动 三、部署kibana 部署kibana 修…

Vitis HLS 学习笔记--抽象并行编程模型-不良示例

目录 1. 简介 2. 基础 kernel 2.1 pass kernel 2.2 double_pass kernel 2.3 add_kernel 2.4 split kernel 3. 三种bypass 3.1 input_bypass 3.2 middle_bypass 3.3 output_bypass 4. 总结 1. 简介 本文展示三个在数据流水线中常见的问题&#xff1a; 输入参数绕过…

DAMA:数据治理 CDGA/CDGP 认证考试备考经验分享

一、关于DAMA中国和CDGA/CDGP考试 国际数据管理协会&#xff08;DAMA国际&#xff09;是一个全球性的专业组织&#xff0c;由数据管理和相关的专业人士组成&#xff0c;非营利性机构&#xff0c;厂商中立。协会自1980年成立以来&#xff0c;一直致力于数据管理和数字化的研究、…

计算机毕业设计hadoop+spark微博舆情大数据分析 微博爬虫可视化 微博数据分析 微博采集分析平台 机器学习(大屏+LSTM情感分析+爬虫)

电商数据建模 一、分析背景与目的 1.1 背景介绍 电商平台数据分析是最为典型的一个数据分析赛道&#xff0c;且电商数据分析有着比较成熟的数据分析模型&#xff0c;比如&#xff1a;人货场模型。此文中我将通过分析国内最大的电商平台——淘宝的用户行为&#xff0c;来巩固数…

WebRTC | 网络传输协议 RTP 和 RTCP

WebRTC | 网络传输协议 RTP 和 RTCP WebRTC | 网络传输协议 RTP 和 RTCP如何选择 TCP 与 UDPRTP概述工作机制报文结构RTP 的使用RTP 拓展头RTP 中的填充数据翻译器和混合器同步控制报文大小wireshark 抓取 RTP 报文 RTCP概述工作机制分组类型报文结构WebRTC 的反馈报文RTPFBPSF…

接口响应断言

目录 接口断言介绍接口断言方式介绍响应状态码断言 课程目标 掌握什么是接口断言。了解接口断言的多种方式。掌握如何对响应状态码完成断言。 思考 这两段代码是完整的接口自动化测试代码吗&#xff1f; …省略… when().get(“https://httpbin.ceshiren.com/get?namead&…

白鹭群优化算法,原理详解,MATLAB代码免费获取

白鹭群优化算法&#xff08;Egret Swarm Optimization Algorithm&#xff0c;ESOA&#xff09;是一种受自然启发的群智能优化算法。该算法从白鹭和白鹭的捕食行为出发&#xff0c;由三个主要部分组成:坐等策略、主动策略和判别条件。将ESOA算法与粒子群算法(PSO)、遗传算法(GA)…

5.24学习记录

[FSCTF 2023]ez_php2 比较简单的pop链 <?php highlight_file(__file__); Class Rd{public $ending;public $cl;public $poc;public function __destruct(){echo "All matters have concluded";die($this->ending);}public function __call($name, $arg){for…