[DPDK][轉]DPDK編程開發(4)—lcore


1、知識百科

 

返回值

操作函數

函數功能

 

RTE_DECLARE_PER_LCORE (unsigned, _lcore_id)

 

 

RTE_DECLARE_PER_LCORE (rte_cpuset_t, _cpuset)

 

static unsigned 

rte_lcore_id (void)

返回當前運行的lcore ID

static unsigned 

rte_get_master_lcore (void)

返回管理lcoreID

static unsigned 

rte_lcore_count (void)

返回系統執行lcore的數目

static int 

rte_lcore_index (int lcore_id)

Return the index of the lcore starting from zero

unsigned 

rte_socket_id (void)

返回正在運行的lcore所對應的物理socket

static unsigned 

rte_lcore_to_socket_id (unsigned lcore_id)

獲得指定lcore的物理socket ID

static int 

rte_lcore_is_enabled (unsigned lcore_id)

判斷lcore是否enabled,如果enable,則返回True

static unsigned 

rte_get_next_lcore (unsigned i, int skip_master, int wrap)

獲得下一個enablelcore ID

int 

rte_thread_set_affinity (rte_cpuset_t *cpusetp)

 

void 

rte_thread_get_affinity (rte_cpuset_t *cpusetp)

 

2、頭文件

#include <rte_per_lcore.h>

#include <rte_eal.h>

#include <rte_launch.h>

 

struct lcore_config lcore_config[RTE_MAX_LCORE]

struct lcore_config {

         unsigned detected;         /**< true if lcore was detected */

         pthread_t thread_id;        /**< pthread identifier */

         int pipe_master2slave[2];    /**< communication pipe with master */

         int pipe_slave2master[2];    /**< communication pipe with master */

         lcore_function_t * volatile f;  /**< function to call */

         void * volatile arg;          /**< argument of function */

         volatile int ret;             /**< return value of function */

         volatile enum rte_lcore_state_t state; /**< lcore state */

         unsigned socket_id;         /**< physical socket id for this lcore */

         unsigned core_id;           /**< core number on socket for this lcore */

};

3、操作函數

rte_lcore_count(void)

函數功能:返回系統執行lcore的數目(和RTE_MAX_LCORE(宏64)不是一樣的概念)。

rte_lcore_id(void)

函數功能:返回當前運行的lcore ID

rte_get_master_lcore(void)

函數功能:返回管理lcoreID

rte_get_next_lcore(unsigned i, int skip_master, int wrap)

函數功能:獲得下一個enablelcore ID

rte_lcore_index(int lcore_id)

函數功能:Return the index of the lcore starting from zero

rte_lcore_is_enabled(unsigned lcore_id)

函數功能:判斷lcore是否enabled,如果enable,則返回True

rte_lcore_to_socket_id(unsigned lcore_id)

函數功能:獲得指定lcore的物理socket ID

rte_socket_id(void)

函數功能:返回正在運行的lcore所對應的物理socket

rte_thread_get_affinity(rte_cpuset_t * cpusetp)

函數功能:獲得當前線程的core affinity

rte_thread_set_affinity(rte_cpuset_t * cpusetp)

函數功能:對當前線程設置core affinity,成功返回0,失敗返回-1

4、知識擴展

NUMA

NUMANon-Uniform Memory Access,非一致性內存訪問)和SMPSymmetric Multi-Processor,對稱多處理器系統)是兩種不同的CPU硬件體系架構。

SMP的主要特征是共享,所有的CPU共享使用全部資源,例如內存、總線和I/O,多個CPU對稱工作,彼此之間沒有主次之分,平等地訪問共享的資源,這樣勢必引入資源的競爭問題,從而導致它的擴展內力非常有限;NUMA架構在中大型系統上一直非常盛行,也是高性能的解決方案,在系統延遲方面表現也都很優秀。

NUMA架構下,CPU的概念從大到小依次是:SocketCoreProcessor。隨着多核技術的發展,我們將多個CPU封裝在一起,這個封裝一般被稱為Socket(插槽),而Socket中的每個核心被稱為Core,為了進一步提升CPU的處理能力,Intel又引入了HTHyper-Threading,超線程)的技術,一個Core打開HT之后,在OS看來就是兩個核,當然這個核是邏輯上的概念,所以也被稱為Logical Processor,本文簡稱為Processor

node

        NUMA體系結構中多了node的概念,主要用於解決core分組問題,在目前常見的分組中,一個socket里有一個node,每個node有自己的內部CPU、總線和內存,同時還可以訪問其他node內的內存,NUMA最大的優勢是可以方便增加CPU數量。

 

#lscpu

#numactl --hardware

 

備注:從指令的結果可以看出本機有1NUMA node。(available: 1 nodes (0)

 

 

備注:從指令的結果可以看出本機有2NUMA node。(available: 2 nodes (0-1)

 

# ls /sys/devices/system/node/node0

 

備注:node0包含0~11processor

socketphysical id

 

一個socket對應主板上的CPU插槽,在/proc/cpuinfo中的physical id就是socketID

# grep 'physical id' /proc/cpuinfo | awk -F: '{print $2 | "sort -un"}'

 

備注:通過以上信息,可以知道本機有2socket,編號為01

 

#grep 'physical id' /proc/cpuinfo | awk -F: '{print $2}' | sort | uniq -c

 

備注:每個socket對應6processer

 

#cat /proc/cpuinfo |grep core|sort -u

 

備注:一個socket6cores,它們的ID分別為0~5

processer

# grep 'processor' /proc/cpuinfo | wc -l

 

備注:本機共有12processor

 

# grep 'siblings' /proc/cpuinfo | sort -u

 

備注:每個socket中有幾個processor也可以從siblings字段中獲取。

cpu.sh

#!/bin/bash

 

# Simple print cpu topology

# Author: kodango

 

function get_nr_processor()

{

    grep '^processor' /proc/cpuinfo | wc -l

}

 

function get_nr_socket()

{

    grep 'physical id' /proc/cpuinfo | awk -F: '{

            print $2 | "sort -un"}' | wc -l

}

 

function get_nr_siblings()

{

    grep 'siblings' /proc/cpuinfo | awk -F: '{

            print $2 | "sort -un"}'

}

 

function get_nr_cores_of_socket()

{

    grep 'cpu cores' /proc/cpuinfo | awk -F: '{

            print $2 | "sort -un"}'

}

 

echo '===== CPU Topology Table ====='

echo

 

echo '+--------------+---------+-----------+'

echo '| Processor ID | Core ID | Socket ID |'

echo '+--------------+---------+-----------+'

 

while read line; do

    if [ -z "$line" ]; then

        printf '| %-12s | %-7s | %-9s |\n' $p_id $c_id $s_id

        echo '+--------------+---------+-----------+'

        continue

    fi

 

    if echo "$line" | grep -q "^processor"; then

        p_id=`echo "$line" | awk -F: '{print $2}' | tr -d ' '`

    fi

 

    if echo "$line" | grep -q "^core id"; then

        c_id=`echo "$line" | awk -F: '{print $2}' | tr -d ' '`

    fi

 

    if echo "$line" | grep -q "^physical id"; then

        s_id=`echo "$line" | awk -F: '{print $2}' | tr -d ' '`

    fi

done < /proc/cpuinfo

 

echo

 

awk -F: '{

    if ($1 ~ /processor/) {

        gsub(/ /,"",$2);

        p_id=$2;

    } else if ($1 ~ /physical id/){

        gsub(/ /,"",$2);

        s_id=$2;

        arr[s_id]=arr[s_id] " " p_id

    }

}

 

END{

    for (i in arr)

        printf "Socket %s:%s\n", i, arr[i];

}' /proc/cpuinfo

 

echo

echo '===== CPU Info Summary ====='

echo

 

nr_processor=`get_nr_processor`

echo "Logical processors: $nr_processor"

 

nr_socket=`get_nr_socket`

echo "Physical socket: $nr_socket"

 

nr_siblings=`get_nr_siblings`

echo "Siblings in one socket: $nr_siblings"

 

nr_cores=`get_nr_cores_of_socket`

echo "Cores in one socket: $nr_cores"

 

let nr_cores*=nr_socket

echo "Cores in total: $nr_cores"

 

if [ "$nr_cores" = "$nr_processor" ]; then

    echo "Hyper-Threading: off"

else

    echo "Hyper-Threading: on"

fi

 

echo

echo '===== END ====='

 

5、常用指令

lscpu

#lscpu

Architecture:          x86_64

CPU op-mode(s):        32-bit, 64-bit

Byte Order:            Little Endian

CPU(s):                            12                 //共有12個邏輯CPU

On-line CPU(s) list:       0-11

Thread(s) per core:       1                  //每個core1threads

Core(s) per socket:       6                  //每個socket6cores

CPU socket(s):               2                  //共有2sockets

NUMA node(s):             2                  //共有2NUMA nodes

Vendor ID:             GenuineIntel

CPU family:                   6

Model:                        45

Stepping:                     7

CPU MHz:              2294.387            //主頻

BogoMIPS:             4588.30

Virtualization:           VT-x

L1d cache:              32K                    //L1 data cache

L1i cache:               32K                    //L1 instruction cache

L2 cache:               256K

L3 cache:               15360K

NUMA node0 CPU(s):     0-5

NUMA node1 CPU(s):     6-11

numactl

#numactl --hardware

 

/proc/cpuinfo

# cat /proc/cpuinfo |grep 'physical id'|awk -F: '{print $2}'|sort|uniq -c

 

備注:可以知道有2socket1socket上有12processor

 

#cat /proc/cpuinfo |grep core|sort -u

 

備注:可以知道1socket上有6cores,結合上個信息,可以知道開啟了超線程。

6、參考資料

lcore

http://www.dpdk.org/doc/api/rte__lcore_8h.html

 

CPU Topology

http://kodango.com/cpu-topology

 

SMP VS NUMA VS MPP

http://xasun.com/article/4d/2076.html

http://www.ibm.com/developerworks/cn/linux/l-numa/index.html

http://blog.csdn.net/ustc_dylan/article/details/45667227


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM