技术分享-DPDK编程实例-HelloWorld
DPDK里的HelloWorld是最基础的入门程序,代码简短,功能也不复杂。它建立了一个多核(线程)运行的基...
DPDK里的HelloWorld是最基础的入门程序,代码简短,功能也不复杂。
它建立了一个多核(线程)运行的基础环境,每个线程会打印“hello from core #”,core # 是由操作系统管理的。如无特别说明,本文里的DPDK线程与硬件线程是一一对应的关系。从代码角度, rte是指runtime environment,eal是指environmentabstraction layer。DPDK的主要对外函数接口都以rte_作为前缀,抽象化函数接口是典型软件设计思路,可以帮助DPDK可以运行多个操作系统上,DPDK官方支持Linux与FreeBSD。和多数并行处理系统类似,DPDK也有主线程,从线程的差异。
int
main(int argc, char **argv)
{
int ret;
unsigned lcore_id;
ret = rte_eal_init(argc, argv);
if (ret < 0)
rte_panic("Cannot init EAL
");
/* call lcore_hello() on every slave lcore */
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
rte_eal_remote_launch(lcore_hello, NULL, lcore_id);
}
/* call it on master lcore too */
lcore_hello(NULL);
rte_eal_mp_wait_lcore();
return 0;
}
1.初始化基础运行环境
主线程运行入口是main函数,调用了rte_eal_init入口函数,启动基础运行环境。
intrte_eal_init(int argc, char **argv);
入口参数是启动DPDK的命令行,可以是长长的一串很复杂的设置,需要深入了解的读者可以查看DPDK相关的文档与源代码liblibrte_ealcommoneal_common_options.c 。对于HelloWorld这个实例,最需要的参数是“-c ”,线程掩码(coremask)指定了需要参与运行的线程(核)集合。rte_eal_init本身所完成的工作是复杂的,它读取入口参数,解析并保存作为DPDK运行的系统信息,依赖这些信息,构建一个针对包处理设计的运行环境。主要动作分解如下
- 配置初始化
- 内存初始化
- 内存池初始化
- 队列初始化
- 告警初始化
- 中断初始化
- PCI初始化
- 定时器初始化
- 检测内存本地化(NUMA)
- 插件初始化
- 主线程初始化
- 轮询设备初始化
- 建立主从线程通道
- 将从线程设置在等待模式
- PCI设备的探测与初始化
2.多核运行初始化
DPDK面向多核设计,程序会试图独占运行在逻辑核(lcore)上。Main函数里重要部分是启动多核运行环境,RTE_LCORE_FOREACH_SLAVE(lcore_id)如名所示,遍历所有EAL指定可以使用的lcore,然后通过rte_eal_remote_launch在每个lcore上,启动被指定的线程。
int rte_eal_remote_launch(int (*f)(void *),
void *arg, unsignedslave_id);
第一个参数是从线程,是被征召的线程,
第二个参数是传给从线程的参数
第三个参数是指定的逻辑核,从线程会执行在这个core上。
具体来说,int rte_eal_remote_launch(lcore_hello,NULL, lcore_id);
参数lcore_id指定了从线程ID,运行入口函数lcore_hello.
运行函数lcore_hello,它读取自己的逻辑核编号(lcore_id), 打印出“hellofrom core #”
static int
lcore_hello(__attribute__((unused)) void *arg)
{
unsigned lcore_id;
lcore_id = rte_lcore_id();
printf("hello from core %u
", lcore_id);
return 0;
}
这是个简单示例,从线程很快就完成了指定工作,在更真实场景里,这个从线程会是一个循环运行的处理过程。
(本文摘自《深入浅出DPDK》,若有购书需求,请点击阅读全文)
关注 DPDK开源社区
微信扫一扫关注公众号