• DPDK helloworld 源码阅读


    在 DPDK Programmer's Guides 中的 EAL 一篇中有一个图可以很清晰地看到一个DPDK的应用程序的大致执行思路:

    初始化检查CPU支持、微架构配置等完成后,执行main()函数。

    1. 第一步是 rte_eal_init(),核心初始化和启动。其中线程使用的是pthread库,创造线程,并设置CPU亲和性:DPDK通常每个核心固定一个pthread,以避免任务切换的开销。
    2. 然后是 other inits,其余对象的初始化(mbuf、mempool、ring、lpm hash table等)都应该作为主 lcore 上整体应用程序初始化的一部分来完成。
    3. rte_eal_remote_lauch(func, NULL, lcore_id),在每个逻辑核上注册一个回调函数。
    4. rte_eal_mp_wait_lcore(),等待各个线程返回。
    5. 继续其余的部分。

    下面对照此思路阅读 /dpdk/examples/helloworld/main.c 这个代码:

    /* SPDX-License-Identifier: BSD-3-Clause
     * Copyright(c) 2010-2014 Intel Corporation
     */
    
    #include <stdio.h>
    #include <string.h>
    #include <stdint.h>
    #include <errno.h>
    #include <sys/queue.h>
    
    #include <rte_memory.h>
    #include <rte_launch.h>
    #include <rte_eal.h>
    #include <rte_per_lcore.h>
    #include <rte_lcore.h>
    #include <rte_debug.h>
    
    static int
    lcore_hello(__attribute__((unused)) void *arg)
    {
    	unsigned lcore_id;
    	lcore_id = rte_lcore_id(); // ⑤ 返回当前执行单元的线程ID
    	printf("hello from core %u
    ", lcore_id);
    	return 0;
    }
    
    int
    main(int argc, char **argv)
    {
    	int ret;
    	unsigned lcore_id;
    
    	ret = rte_eal_init(argc, argv);  // ① 初始化EAL
    	if (ret < 0)
    		rte_panic("Cannot init EAL
    ");
    
    	RTE_LCORE_FOREACH_SLAVE(lcore_id) { // ② 浏览除主lcore之外的所有lcore
    		rte_eal_remote_launch(lcore_hello, NULL, lcore_id); // ③ 在lcore上执行函数
    	}
    
    	lcore_hello(NULL);
    
    	rte_eal_mp_wait_lcore(); // ④ 等待lcore完成工作
    	return 0;
    }
    

    rte_eal_init()初始化环境抽象层(EAL)。此函数仅在应用程序的main()函数中尽快在MASTER lcore上执行。
    ② 宏:RTE_LCORE_FOREACH_SLAVE(i) :浏览除主lcore之外的所有正在运行的lcores。

    #define RTE_LCORE_FOREACH_SLAVE(i)	
    Value:
    for (i = rte_get_next_lcore(-1, 1, 0);                          
                 i<RTE_MAX_LCORE;                                           
                 i = rte_get_next_lcore(i, 1, 0))
    

    rte_eal_remote_launch(lcore_hello, NULL, lcore_id);在另一个lcore上启动一个函数。应仅在MASTER lcore上执行。第一个参数是函数名,第二个参数是以什么参数执行该函数,第三个参数是逻辑核的ID。
    rte_eal_mp_wait_lcore();应仅在MASTER lcore上执行,等到lcore完成它的工作。一个lcore有三种状态:WAIT、RUNNING、FINISHED,对应空闲、正在执行一个函数、执行完成。依据三个状态来协调线程的launch和wait。
    rte_lcore_id() 返回执行单元的线程ID


    API 文档:

  • 相关阅读:
    BZOJ 2154 Crash的数字表格 【莫比乌斯反演】
    BZOJ 3529 [Sdoi2014]数表 【莫比乌斯反演】
    BZOJ 2820 YY的GCD 【莫比乌斯反演】
    BZOJ 2440 [中山市选2011]完全平方数 【莫比乌斯反演】
    [BalticOI 2004] Sequence
    AtCoder [ARC070E] NarrowRectangles
    AtCoder [AGC022E] Median Replace
    AtCoder [ARC101E] Ribbons on Tree
    CF107D Crime Management
    Loj 6497「雅礼集训 2018 Day1」图
  • 原文地址:https://www.cnblogs.com/ZCplayground/p/9317194.html
Copyright © 2020-2023  润新知