DPDK-Hello-World示例应用程序

前言

目标: 在linux上安装DPDK的程序编写环境,编写和运行DPDK的hello world程序。

声明:我不清楚DPDK具体是个啥。DPDK的目的大概是:原先的网络数据需要从内核层拷贝到用户层,在IO越来越快的今天,CPU的处理就显得有点慢。DPDK可以跳过内核,实现更快的数据包处理。

环境安装

阅读:DPDK-系统要求从源代码编译DPDK目标

首先是系统要求,需要在内核中启用 HUGETLBFS 选项。然后是开启大页。

第一种是我喜欢用的,使用DPDK中的dpdk-hugepages.py

# 查看当前系统的大页情况
./dpdk-hugepages.py -s

# 创建挂载点
# sudo  mkdir -p  /dev/hugepages

# 创建大页。每个页面2M,总共创建1G大页
sudo ./dpdk-hugepages.py -p 2048K --setup 1G

第二种是,设置启动参数:linux大页内存使用,教你如何解决DPDK内存大页在NUMA架构重分配问题

default_hugepagesz=1G hugepagesz=1G hugepages=1设置到/etc/default/grub中的GRUB_CMDLINE_LINUX中,然后运行update-grub更新启动参数配置文件 /boot/grub/grub.cfg。之后重新启动,cat /proc/meminfo就能看到系统中显示大页数量和剩余的数量(这个图是配置的2M的页)。

接着是,编译DPDK。emm,我目前不清楚那些编译选项的具体内容。那直接使用包管理器安装吧,当前够用就好。

# almlinux9
# sudo dnf remove dpdk dpdk-devel dpdk-tools 

# ubuntu22
sudo apt install libhugetlbfs-bin dpdk-dev libdpdk-dev

编写hello-world程序

阅读:Hello World 示例应用程序

这是一个最简单的 DPDK 应用程序示例。该应用程序只是在每个启用的 lcore 上打印一条“helloworld”消息。

lcore是啥?

我们可以看下这个链接: 环境抽象层 (EAL)

环境抽象层 (Environment Abstraction Layer, EAL) 负责访问低级资源,例如硬件和内存空间。它提供了一个通用接口,对应用程序和库隐藏了环境细节。初始化例程负责决定如何分配这些资源(即内存空间、设备、定时器、控制台等)。

术语“lcore”指的是 EAL 线程。DPDK 通常为每个核心固定一个 pthread,以避免任务切换的开销。这可以显着提高性能,但缺乏灵活性并且并不总是高效。当使用多个 pthread 时,EAL pthread 和指定的物理 CPU 之间的绑定不再总是 1:1…

下面是示例代码,修改自:helloworld

#include <rte_eal.h>
#include <rte_lcore.h>
#include <stdio.h>

int lcore_hello(__rte_unused void *arg) {
  unsigned int lcore_id = rte_lcore_id();
  printf("hello from core %u\n", lcore_id);
  return 0;
}

int main(int argc, char *argv[]) {
  if (rte_eal_init(argc, argv) < 0) {
    rte_exit(EXIT_FAILURE, "fail in init");
  }
  for (unsigned int lcore_id = rte_get_next_lcore(-1, 1, 0);
       lcore_id < RTE_MAX_LCORE;
       lcore_id = rte_get_next_lcore(lcore_id, 1, 0)) {
    rte_eal_remote_launch(lcore_hello, NULL, lcore_id);
  }

  lcore_hello(NULL);

  rte_eal_mp_wait_lcore(); // Wait until all lcores finish their jobs.

  rte_eal_cleanup();

  return 0;
}

下面逐行介绍下上面的API。由于所有的API接口文档,都可以在DPDK-API查看。所以这里仅仅简单介绍下程序中使用的API。

  • rte_eal_init: 初始化EAL, 仅在main lcore上执行。
  • rte_exit:终止程序,打印错误消息,错误码返回到shell。
  • rte_get_next_lcore: 获取下一个启用的lcore ID。
  • rte_eal_remote_launch: 向处于 WAIT 状态的工作线程 lcore发送消息。当远程lcore收到消息时,它切换到RUNNING状态,然后执行函数。执行完成后,远程 lcore 切换到 WAIT 状态,并且函数的返回值存储在本地变量中,以便使用rte_eal_wait_lcore()读取。
  • rte_eal_cleanup: 清理EAL。

下面来编译程序。这里通过cmake来构建。

cmake_minimum_required(VERSION 3.11)

project(dpdk_hello_world)

find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBDPDK REQUIRED libdpdk)
include_directories(${LIBDPDK_INCLUDE_DIRS})
link_directories(${LIBDPDK_LIBRARY_DIRS})
message(STATUS "LIBDPDK_LIBRARIES: ${LIBDPDK_LIBRARIES}")
message(STATUS "LIBDPDK_INCLUDE_DIRS: ${LIBDPDK_INCLUDE_DIRS}")
message(STATUS "LIBDPDK_LIBRARY_DIRS: ${LIBDPDK_LIBRARY_DIRS}")

add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE ${LIBDPDK_LIBRARIES})

编译和运行程序。

mkdir build; cd build; cmake ..; make

# 在wsl中运行
EAL: Detected CPU lcores: 16
EAL: Detected NUMA nodes: 1
EAL: Detected shared linkage of DPDK
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
EAL: No available 1048576 kB hugepages reported
EAL: VFIO support initialized
TELEMETRY: No legacy callbacks, legacy socket not created
hello from core 1
hello from core 2
hello from core 3
hello from core 4
hello from core 5
hello from core 6
hello from core 7
hello from core 8
hello from core 9
hello from core 10
hello from core 11
hello from core 12
hello from core 13
hello from core 14
hello from core 15
hello from core 0
  • 22
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

da1234cao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值