DPDK 源碼的不完全筆記(一) 初識DPDK

寫在前面

本系列記錄了作者在項目過程中由於好奇心驅使而瞭解到的部分DPDK實現細節。比較適合有同樣好奇心的DPDK初學者,通過本系列文章

您可以學習到

  • DPDK的整體工作原理以及部分實現細節

您不能學習到

  • 應用DPDK進行性能調優

如果對DPDK的起源不是很清楚的話,可以先瀏覽下 絕對乾貨!初學者也能看懂的DPDK解析,重點就是Linux + x86網絡IO瓶頸 這部分,總結一句話就是Linux內核協議棧太慢了,爲了突破這種性能瓶頸,DPDK的方案是繞過(bypass)內核,直接從網卡把數據抓到用戶空間。

一些基本的概念

EAL

首先必須明白的一點就是,DPDK是以若干個lib的形式提供給應用鏈接使用,其中最終要的一個lib就是EAL了,EAL的全稱是(Environment Abstraction Layer, 環境抽象層),它負責爲應用間接訪問底層的資源,比如內存空間、線程、設備、定時器等。如果把我們的應用比作一個豪宅的主人的話,EAL就是這個豪宅的管家。

lcore & socket

這兩個概念在 DPDK的代碼中隨處可見,注意這裏的 socket 不是網絡編程裏面的那一套東西,而是CPU相關的東西。具體的概念可以參看Differences between physical CPU vs logical CPU vs Core vs Thread vs Socket 或者其翻譯版本physical CPU vs logical CPU vs Core vs Thread vs Socket(翻譯)

對我們來說,只要知道可以DPDK可以運行在多個lcore上就足夠了.

DPDK 如何知道有多少個lcore呢 ? 在啓動時解析文件系統中的特定文件就可以了, 參考函數eal_cpu_detected

DPDK的運行形式

大部分DPDK的代碼是以lib的形式運行在用戶應用的進程上下文.爲了達到更高的性能。應用通常都會多進程或者多線程的形式運行在不同的lcore

多線程的場景:

mutil thread

多進程的場景:

多進程的場景下,多個應用實例如何保證關鍵信息(比如內存資源)的一致性呢? 答案是不同進程將公共的數據mmap同一個文件,這樣任何一個進程對數據的修改都可以影響到其他進程。

multi process

Primary & Secondary

多進程場景下,進程有兩種角色Primary或者Secondary,正如其名字,Primary進程可以create 資源,而Secondary進程只能 attach已存在的資源。一山不容二虎,一個多進程的應用,有且只有一個Primary進程,其餘都是Secondary進程。應用可以通過命令行參數 --proc-type 來指定應用類型。

DPDK的入口

如同main函數在應用程序中的地位,rte_eal_init函數便是DPDK夢開始的地方(其實前面的圖已經畫出來了!),我們來看看它做了什麼事。

/* Launch threads, called at application init(). */
int
rte_eal_init(int argc, char **argv)
{
    thread_id = pthread_self();

    rte_eal_cpu_init();

    eal_parse_args(argc, argv);

    rte_config_init();

    rte_eal_intr_init();

    rte_mp_channel_init();
    
    rte_eal_memzone_init();
    
    rte_eal_memory_init();

    rte_eal_malloc_heap_init()
    
    eal_thread_init_master(rte_config.master_lcore);

    RTE_LCORE_FOREACH_SLAVE(i) {
        /* create a thread for each lcore */
        ret = pthread_create(&lcore_config[i].thread_id, NULL,
                     eal_thread_loop, NULL);
    
        .....
    }

    /*
     * Launch a dummy function on all slave lcores, so that master lcore
     * knows they are all ready when this function returns.
     */
    rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER);
    
    rte_eal_mp_wait_lcore();

    ......
}  

總結起來就是

  • 檢測lcore
  • 解析用戶的命令行參數
  • 內存資源等子模塊初始化
  • 在其他lcore上啓動線程
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章