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) |
返回管理lcore的ID |
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) |
獲得下一個enable的lcore 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)
函數功能:返回管理lcore的ID。
rte_get_next_lcore(unsigned i, int skip_master, int wrap)
函數功能:獲得下一個enable的lcore 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
NUMA(Non-Uniform Memory Access,非一致性內存訪問)和SMP(Symmetric Multi-Processor,對稱多處理器系統)是兩種不同的CPU硬件體系架構。
SMP的主要特征是共享,所有的CPU共享使用全部資源,例如內存、總線和I/O,多個CPU對稱工作,彼此之間沒有主次之分,平等地訪問共享的資源,這樣勢必引入資源的競爭問題,從而導致它的擴展內力非常有限;NUMA架構在中大型系統上一直非常盛行,也是高性能的解決方案,在系統延遲方面表現也都很優秀。
在NUMA架構下,CPU的概念從大到小依次是:Socket、Core、Processor。隨着多核技術的發展,我們將多個CPU封裝在一起,這個封裝一般被稱為Socket(插槽),而Socket中的每個核心被稱為Core,為了進一步提升CPU的處理能力,Intel又引入了HT(Hyper-Threading,超線程)的技術,一個Core打開HT之后,在OS看來就是兩個核,當然這個核是邏輯上的概念,所以也被稱為Logical Processor,本文簡稱為Processor。
node
NUMA體系結構中多了node的概念,主要用於解決core分組問題,在目前常見的分組中,一個socket里有一個node,每個node有自己的內部CPU、總線和內存,同時還可以訪問其他node內的內存,NUMA最大的優勢是可以方便增加CPU數量。
#lscpu
#numactl --hardware
備注:從指令的結果可以看出本機有1個NUMA node。(available: 1 nodes (0))
備注:從指令的結果可以看出本機有2個NUMA node。(available: 2 nodes (0-1))
# ls /sys/devices/system/node/node0
備注:node0包含0~11個processor。
socket(physical id)
一個socket對應主板上的CPU插槽,在/proc/cpuinfo中的physical id就是socket的ID。
# grep 'physical id' /proc/cpuinfo | awk -F: '{print $2 | "sort -un"}'
備注:通過以上信息,可以知道本機有2個socket,編號為0和1。
#grep 'physical id' /proc/cpuinfo | awk -F: '{print $2}' | sort | uniq -c
備注:每個socket對應6個processer。
#cat /proc/cpuinfo |grep core|sort -u
備注:一個socket有6個cores,它們的ID分別為0~5。
processer
# grep 'processor' /proc/cpuinfo | wc -l
備注:本機共有12個processor。
# 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 //每個core有1個threads
Core(s) per socket: 6 //每個socket有6個cores
CPU socket(s): 2 //共有2個sockets
NUMA node(s): 2 //共有2個NUMA 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
備注:可以知道有2個socket,1個socket上有12個processor。
#cat /proc/cpuinfo |grep core|sort -u
備注:可以知道1個socket上有6個cores,結合上個信息,可以知道開啟了超線程。
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