玩转CPU Topology.docx
- 文档编号:26920537
- 上传时间:2023-06-24
- 格式:DOCX
- 页数:21
- 大小:443.60KB
玩转CPU Topology.docx
《玩转CPU Topology.docx》由会员分享,可在线阅读,更多相关《玩转CPU Topology.docx(21页珍藏版)》请在冰豆网上搜索。
玩转CPUTopology
玩转CPU拓扑
NUNA与SMP
NUMA(Non-UniformMemoryAccess,非一致性内存访问)和SMP(SymmetricMulti-Processor,对称多处理器系统)是两种不同的CPU硬件体系架构。
SMP的主要特征是共享,所有的CPU共享使用全部资源,例如内存、总线和I/O,多个CPU对称工作,彼此之间没有主次之分,平等地访问共享的资源,这样势必引入资源的竞争问题,从而导致它的扩展内力非常有限。
NUMA技术将CPU划分成不同的组(Node),每个Node由多个CPU组成,并且有独立的本地内存、I/O等资源。
Node之间通过互联模块连接和沟通,因此除了本地内存外,每个CPU仍可以访问远端Node的内存,只不过效率会比访问本地内存差一些,我们用Node之间的距离(Distance,抽象的概念)来定义各个Node之间互访资源的开销。
Node->Socket->Core->Processor
如果你只知道CPU这么一个概念,那么是无法理解CPU的拓扑的。
事实上,在NUMA架构下,CPU的概念从大到小依次是:
Node、Socket、Core、Processor。
Node的概念在上一节已经介绍过,这里就不多赘述了。
随着多核技术的发展,我们将多个CPU封装在一起,这个封装一般被称为Socket(插槽的意思,也有人称之为Packet,不知到哪个更加准确?
),而Socket中的每个核心被称为Core。
为了进一步提升CPU的处理能力,Intel又引入了HT(Hyper-Threading,超线程)的技术,一个Core打开HT之后,在OS看来就是两个核,当然这个核是逻辑上的概念,所以也被称为LogicalProcessor,本文简称为Processor。
综上所述,一个NUMANode可以有一个或者多个Socket,一个多核Socket显然包含多个Core,一个Core如果打开HT则变成两个LogicalProcessor。
Logicalprocessor只是OS内部看到的,实际上两个Processor还是位于同一个Core上,所以频繁的调度仍可能导致资源竞争,影响性能。
查看CPUTopology
在介绍完CPU拓扑相关的概念后,我们来实际在服务器上查看相关的信息。
查看NumaNode
numactl是设定进程NUMA策略的命令行工具,也可以用来查看当前的Nuwanode:
$numactl--hardware
available:
2nodes(0-1)
node0size:
24211MB
node0free:
110MB
node1size:
24240MB
node1free:
150MB
nodedistances:
node01
0:
1020
1:
2010
从上面可以看出本机有两个Numanode,如果要进一步知道一个Node包含哪几个CPU,该怎么办?
一种方法是通过查看ls/sys/devices/system/node/目录下的信息,例如:
$ls/sys/devices/system/node/node0
cpu12cpu13cpu14cpu15cpu4cpu5cpu6cpu7cpumapdistancememinfonumastat
可见,node0包含4/5/6/7/12/13/14/15八个Processor(刚好是一个Socket)。
如果是xen的环境,还可以通过xminfo来查看,对应的是node_to_cpu字段。
查看Socket
一个Socket对应主板上的一个插槽,在本文中是指一个CPU封装。
在/proc/cpuinfo中的physicalid就是Socket的ID,可以从中找到本机到底有多少个Socket,并且每个Socket有那几个Processor。
1)查看有几个Socket
$grep'physicalid'/proc/cpuinfo|awk-F:
'{print$2|"sort-un"}'
0
1
$grep'physicalid'/proc/cpuinfo|awk-F:
'{print$2|"sort-un"}'|wc-l
2
2)查看每个Socket有几个Processor
$grep'physicalid'/proc/cpuinfo|awk-F:
'{print$2}'|sort|uniq-c
80
81
3)查看Socket对应那几个Processor
$awk-F:
'{
if($1~/processor/){
gsub(//,"",$2);
p_id=$2;
}elseif($1~/physicalid/){
gsub(//,"",$2);
s_id=$2;
arr[s_id]=arr[s_id]""p_id
}
}
END{
for(iinarr)
printarr[i];
}'/proc/cpuinfo|cut-c2-
456712131415
0123891011
查看Core
/proc/cpuinfo文件中的cpucores表明一个socket中有几个cores,例如:
cat/proc/cpuinfo|grep'core'|sort-u
coreid:
0
coreid:
1
coreid:
10
coreid:
9
cpucores:
4
上面的结果说明一个socket有4个cores,它们的id分别为0/1/9/10,根据之前查到的我们的机器有2个socket,所以总共有8个core。
查看Processor
查看Processors的个数就比较简单了,从上面的统计结果中我们已经可以知道有16个Logicalprocessor,不过也可以直接从/proc/cpuinfo文件中获取:
$grep'processor'/proc/cpuinfo|wc-l
16
其实,每个socket中能有几个processor也可以从siblings字段中获取:
$grep'siblings'/proc/cpuinfo|sort-u
siblings:
8
信息汇总(CPU信息查看脚本)
基于以上查看CPU拓扑信息的方法,简单的写了一个小程序来查询:
#!
/bin/bash
#Simpleprintcputopology
#Author:
kodango
functionget_nr_processor()
{
grep'^processor'/proc/cpuinfo|wc-l
}
functionget_nr_socket()
{
grep'physicalid'/proc/cpuinfo|awk-F:
'{
print$2|"sort-un"}'|wc-l
}
functionget_nr_siblings()
{
grep'siblings'/proc/cpuinfo|awk-F:
'{
print$2|"sort-un"}'
}
functionget_nr_cores_of_socket()
{
grep'cpucores'/proc/cpuinfo|awk-F:
'{
print$2|"sort-un"}'
}
echo'=====CPUTopologyTable====='
echo
echo'+--------------+---------+-----------+'
echo'|ProcessorID|CoreID|SocketID|'
echo'+--------------+---------+-----------+'
whilereadline;do
if[-z"$line"];then
printf'|%-12s|%-7s|%-9s|\n'$p_id$c_id$s_id
echo'+--------------+---------+-----------+'
continue
fi
ifecho"$line"|grep-q"^processor";then
p_id=`echo"$line"|awk-F:
'{print$2}'|tr-d''`
fi
ifecho"$line"|grep-q"^coreid";then
c_id=`echo"$line"|awk-F:
'{print$2}'|tr-d''`
fi
ifecho"$line"|grep-q"^physicalid";then
s_id=`echo"$line"|awk-F:
'{print$2}'|tr-d''`
fi
done
echo
awk-F:
'{
if($1~/processor/){
gsub(//,"",$2);
p_id=$2;
}elseif($1~/physicalid/){
gsub(//,"",$2);
s_id=$2;
arr[s_id]=arr[s_id]""p_id
}
}
END{
for(iinarr)
printf"Socket%s:
%s\n",i,arr[i];
}'/proc/cpuinfo
echo
echo'=====CPUInfoSummary====='
echo
nr_processor=`get_nr_processor`
echo"Logicalprocessors:
$nr_processor"
nr_socket=`get_nr_socket`
echo"Physicalsocket:
$nr_socket"
nr_siblings=`get_nr_siblings`
echo"Siblingsinonesocket:
$nr_siblings"
nr_cores=`get_nr_cores_of_socket`
echo"Coresinonesocket:
$nr_cores"
letnr_cores*=nr_socket
echo"Coresintotal:
$nr_cores"
if["$nr_cores"="$nr_processor"];then
echo"Hyper-Threading:
off"
else
echo"Hyper-Threading:
on"
fi
echo
echo'=====END====='
执行结果为:
=====CPUTopologyTable=====
+--------------+---------+-----------+
|ProcessorID|CoreID|SocketID|
+--------------+---------+-----------+
|0|0|1|
+--------------+---------+-----------+
|1|1|1|
+--------------+---------+-----------+
|2|9|1|
+--------------+---------+-----------+
|3|10|1|
+--------------+---------+-----------+
|4|0|0|
+--------------+---------+-----------+
|5|1|0|
+--------------+---------+-----------+
|6|9|0|
+--------------+---------+-----------+
|7|10|0|
+--------------+---------+-----------+
|8|0|1|
+--------------+---------+-----------+
|9|1|1|
+--------------+---------+-----------+
|10|9|1|
+--------------+---------+-----------+
|11|10|1|
+--------------+---------+-----------+
|12|0|0|
+--------------+---------+-----------+
|13|1|0|
+--------------+---------+-----------+
|14|9|0|
+--------------+---------+-----------+
|15|10|0|
+--------------+---------+-----------+
Socket0:
456712131415
Socket1:
0123891011
=====CPUInfoSummary=====
Logicalprocessors:
16
Physicalsocket:
2
Siblingsinonesocket:
8
Coresinonesocket:
4
Coresintotal:
8
Hyper-Threading:
on
=====END=====
玩转CPUTopology
先温习几个概念
请原谅对部分术语笔者直接引用了wikipedia上的英文解释,因为哥实在做不到比wikipedia上更准确描述。
我会试着解释部分的术语,并在本节的最后梳理一下这些术语之间的关系。
注意,笔者对由于不准确的描述导致的性能下降,进程crash等任何问题不承担任何责任☺
NUMA:
Non-UniformMemoryAccess(NUMA)isacomputermemorydesignusedinmultiprocessing,wherethememoryaccesstimedependsonthememorylocationrelativetoaprocessor.UnderNUMA,aprocessorcanaccessitsownlocalmemoryfasterthannon-localmemory,thatis,memorylocaltoanotherprocessorormemorysharedbetweenprocessors.NUMAarchitectureslogicallyfollowinscalingfromsymmetricmultiprocessing(SMP)architectures.
提到NUMA就不能不对比SMP,
SMP:
Symmetricmultiprocessing(SMP)involvesamultiprocessorcomputerhardwarearchitecturewheretwoormoreidenticalprocessorsareconnectedtoasinglesharedmainmemoryandarecontrolledbyasingleOSinstance.
说了这么多其实都是为了介绍NUMANode:
Afairlytechnicallycorrectandalsofairlyuglydefinitionofanodeis:
aregionofmemoryinwhicheverybytehasthesamedistancefromeachCPU.
Amorecommondefinitionis:
ablockofmemoryandtheCPUs,I/O,etc.physicallyonthesamebusasthememory.
CPU:
这个不解释,原因你懂得。
想当年CPU拼的是频率,频率越高越NB,但是提升频率和制程密切相关。
但是制程这玩意有一个物理天花板,提升越来越难,有报道指出,现阶段普遍应用的硅晶体管在尺寸上有一个10nm的物理极限。
为了提升性能cpu走上了多核的道路,即在一个封装(socket或者processor)里放多个core。
这还不够,又发明了超线程技术Hyper-threading
HT:
HTTechnologyisusedtoimproveparallelizationofcomputations(doingmultipletasksatonce)performedonPCmicroprocessors.Foreachprocessorcorethatisphysicallypresent,theoperatingsystemaddressestwovirtualorlogicalcores,andsharestheworkloadbetweenthemwhenpossible.TheyappeartotheOSastwoprocessors,thustheOScanscheduletwoprocessesatonce.一个core在HT之后OS看到的就是2个LogicalProcessor。
下图展示了这些术语之间的逻辑关系:
一个NUMAnode包括一个或者多个Socket,以及与之相连的localmemory。
一个多核的Socket有多个Core。
如果CPU支持HT,OS还会把这个Core看成2个LogicalProcessor。
为了避免混淆,在下文中统一用socket指代ProcessororSocket;为了偷懒,下文中用Processor指代LogicalProcessor,击键能省则省不是。
查看CPUTopology
本文以笔者能访问的某台RedHatEnterpriseLinuxServerrelease5.4为例介绍,其他系统请自行google。
NUMANode
第一种方法使用numactl查看
numactl–hardware
available:
2nodes(0-1) //当前机器有2个NUMAnode,编号0&1
node0size:
12091MB //node0物理内存大小
node0free:
988MB //node0当前free内存大小
node1size:
12120MB
node1free:
1206MB
nodedistances:
//node距离,可以简单认为是CPU本node内存访问和跨node内存访问的成本。
从下表可知跨node的内存访问成本(20)是本地node内存(10)的2倍。
node 0 1
0:
10 20
1:
20 10
第二种方法是通过sysfs查看,这种方式可以查看到更多的信息
ls/sys/devices/system/node/
node0 node1//两个目标表示本机有2个node,每个目录内部有多个文件和子目录描述node内cpu,内存等信息。
比如说node0/meminfo描述了node0内存相关信息。
Socket
可以直接通过/proc/cpuinfo查看,cpuinfo里的physicalid描述的就是Socket的编号,
cat/proc/cpuinfo|grep“physicalid”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
]
physicalid :
0
physicalid :
0
physicalid :
0
physicalid :
0
physicalid :
1
physicalid :
1
physicalid :
1
physicalid :
1
physicalid :
0
physicalid :
0
physicalid :
0
physicalid :
0
physicalid :
1
physicalid :
1
physicalid :
1
physicalid :
1
由上可知本机有2个Socket,编号为0和1。
还可以简单的使用如下命令直接查看Socket个数
cat/proc/cpuinfo|grep“physicalid”|sort-u|wc–l
2 //本机有2个物理CPU封装
Core
仍然是可以通过/proc/cpuinfo查看,cpuinfo中跟core相关的信息有2行。
cpucores:
4//一个socket有4个核,
coreid:
1//一个core在socket内的编号
通过如下命令可以直接查看core的数量
cat/proc/cpuinfo|grep“cpucores”|uniq|cut-d:
-f2
4 //1个socket有4个core
本机有2个socket,每个有4个core,所以一共有8个core
还可以查看core在Socket里的编号
cat/proc/cpuinfo|grep“coreid”|sort-u
1
2
3
4
coreid :
0
coreid :
1
coreid :
10
coreid :
9
一个socket里面4个core的编号为0,1,9,10。
是的,coreid是不连续的。
如果谁知道为啥麻烦通知我,先谢了。
LogicalProcessor
仍然是可以通过/proc/cpuinfo查看在OS的眼里有多少个LogicalProcessor
cat/proc/cpuinfo|grepprocessor|wc–l
1
Ok,8个core变成了16个LogicalProcessor,所以本机开启了HT。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 玩转CPU Topology CPU