我们开发普通应用程序时一般很少关心CPU信息,但是涉及到CPU多核编程时就需要对CPU有一个基本了理解。在Linux下我们了解CPU信息通常有两个途径:

  1. 通过命令 lscpu 来查看CPU概要信息

  2. 通过命令 cat /proc/cpuinfo 来查看每个CPU 逻辑核 对应信息

本文将详细解读这两个命令输出内容分别有什么含义。

硬件组成

在解读 CPU 信息之前需要先了解一些硬件组成信息。

./cpu.assets/mainboard-notes.jpg

首先,从上图可以看出 CPU 是安装在主板(mainboard)上的,主板上安装 CPU 的插槽就称之为 socket 。一个主板一般会有一个或多个 socket ,每个 socket 只可以插入一个 CPU

其次,每个物理 CPU 内部又会有一个或多少物理核心,这个核心切切实实存在的硬件芯片。

./cpu.assets/cores-hand.jpg

但是在实际开发中,我们接触的都是 逻辑核 的概念,简单的地说,如果 CPU 支持 Hyper-Threading 那么启用 Hyper-Threading 后,每个物理核都会划分成 n 个逻辑核, nHyper-Threading 的数量。

介绍到这里,硬件组成就结束了,总结一下提到的各个术语:

  • socket :主板上的 CPU 插槽

  • CPU(Central Processing Unit) :完整的 CPU 硬件,可以插入主板的硬件。

  • 物理核(Physical core/processor)CPU 内部存在的硬件物理核心,可以看的到的,有独立的电路元件以及L1,L2缓存,可以独立地执行指令。

  • 逻辑核(Logical core/processor) : 在同一个物理核内,逻辑层面的核。

  • 超线程(Hyper-Threading) : 超线程技术就是让一个核模拟出两个核的技术。

最后整体看一下 socketCPUphysical corelogical core 之间的关系:

./cpu.assets/socket-cpu-cores.png

上图表示一个 socket(深灰色) 内部插入了一块 CPU(灰色) , 这块 CPU 有4个 物理核(绿色) ,每个物理核有两个 逻辑核(橙色)

一台主机最终的逻辑核的数量计算公式为: 逻辑核数 = 物理核数 * 超线程数 * socket(CPU)数

查看CPU信息

通过 lscpu 命令查看

  [root@xeon ~]# lscpu
  Architecture:          x86_64
  CPU op-mode(s):        32-bit, 64-bit
  Byte Order:            Little Endian
  CPU(s):                40
  On-line CPU(s) list:   0-39
  Thread(s) per core:    2
  Core(s) per socket:    10
  Socket(s):             2
  NUMA node(s):          2
  Vendor ID:             GenuineIntel
  CPU family:            6
  Model:                 62
  Model name:            Intel(R) Xeon(R) CPU E5-2690 v2 @ 3.00GHz
  Stepping:              4
  CPU MHz:               1202.819
  BogoMIPS:              6017.30
  Virtualization:        VT-x
  L1d cache:             32K
  L1i cache:             32K
  L2 cache:              256K
  L3 cache:              25600K
  NUMA node0 CPU(s):     0-9,20-29
  NUMA node1 CPU(s):     10-19,30-39
  • Architecture: CPU的架构信息,上面信息表示这是一个x86架构的64位CPU。

  • CPU op-mode(s): CPU支持的模式 32位、64位。

  • Byte Order:CPU字节序,上面信息表示这是个小端机器。

  • CPU(s): CPU 逻辑核 数量,上面信息表示这台机器有40个逻辑核。

  • On-line CPU(s) list: 在线CPU列表。

  • Thread(s) per core:每个 物理核 开启的超线程数量,如果不支持或没有开启超线程,该值为1。上面信息表示每个物理核开启2个超线程。

  • Core(s) per socket: 每个CPU插槽有多少个 物理核 ,上面信息表示这台机器每个 socket 有10个物理核。

  • Socket(s): 主板上有多少个CPU插槽。上面信息表示这台机器有2个CPU插槽。

  • NUMA node(s): 有多少个NUMA节点。上面信息表示这台机器有2个NUMA节点。

  • Vendor ID: CPU制造商标识。

  • CPU family: CPU产品系列标识

  • Model: 第几代CPU标识

  • Model name: CPU型号名称。

  • Stepping: CPU版本号。

  • CPU MHz: 当前运行频率。

  • CPU max MHz: CPU最大运行频率。

  • CPU min MHz: CPU最低运行频率。

  • BogoMIPS: CPU 每秒钟什么都不能做的百万指令次数。上面信息表示这台机器CPU每秒可以执行60亿零1千7百三十万次指令。

  • Virtualization: 支持虚拟化。

  • L1d cache: CPU数据一级缓存大小。

  • L1i cache: CPU指令一级缓存大小。

  • L2 cache:CPU二级缓存大小。

  • L3 cache: CPU三级缓存大小。

  • NUMA node0 CPU(s): 位于NUMA node0的CPU 逻辑核 编号。

  • NUMA node1 CPU(s): 位于NUMA node1的CPU 逻辑核 编号。

通过 cat /proc/cpuinfo 命令查看

  [root@xeon ~]# cat /proc/cpuinfo | head -27
  processor       : 0
  vendor_id       : GenuineIntel
  cpu family      : 6
  model           : 62
  model name      : Intel(R) Xeon(R) CPU E5-2690 v2 @ 3.00GHz
  stepping        : 4
  microcode       : 0x416
  cpu MHz         : 1199.890
  cache size      : 25600 KB
  physical id     : 0
  siblings        : 20
  core id         : 0
  cpu cores       : 10
  apicid          : 0
  initial apicid  : 0
  fpu             : yes
  fpu_exception   : yes
  cpuid level     : 13
  wp              : yes
  flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm epb tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt dtherm ida arat pln pts
  bugs            :
  bogomips        : 5999.64
  clflush size    : 64
  cache_alignment : 64
  address sizes   : 46 bits physical, 48 bits virtual
  power management:

/proc/cpuinfo 这个文件里记录的是每个 逻辑核 的信息。

  • processor: 当前 逻辑核 编号

  • physical id: 物理CPU 编号(注意不是物理核,是完整的CPU),该值表明当前逻辑核位于哪颗 CPU 上。不同的 physical id 值,表示不同的CPU。这个编号不一定连续。

  • siblings: 表示与当前逻辑核所在的 CPU 中有一共有少个逻辑核。

  • core id: 当前逻辑核所在的 物理核 编号,不同的 CPU 可以有相同的 物理核 编号,即该编号只在同一个CPU内唯一,这个编号不一定连续。

  • cpu cores: 当前 逻辑核 所在的 CPU 有多个个 物理核 。如果当前逻辑核的 siblings 的值和 cpu cores 值不相等,说明当前机器开启了超线程( Hyper-Threading )。

对于逻辑核比较多情况,直接查看 /proc/cpuinfo 数据量太多, 可以根据需要通过不同的命令来筛选:

  1. 统计当前机器有多少个 逻辑核grep processor /proc/cpuinfo | wc -l

  2. 统计当前机器有多少个 CPUgrep "physical id" /proc/cpuinfo | sort -u | wc -l

我把 /proc/cpuinfo 内容中部分字段整理成表格形式,这样我们就可以直观的解读每个 逻辑核 信息,以 27逻辑核 为例:

  • 逻辑核 位于 0CPU 中 ( physical id == 0

  • 逻辑核 所在 CPU 共有 20 个 逻辑核siblings == 20

  • 逻辑核 所在 物理核 编号是 10 ( core id == 10 )

  • 逻辑核 所有 CPU 共有 10 个 物理核 ( cpu cores == 10 )

processor physical id siblings core id cpu cores
0 0 20 0 10
1 0 20 1 10
2 0 20 2 10
3 0 20 3 10
4 0 20 4 10
5 0 20 8 10
6 0 20 9 10
7 0 20 10 10
8 0 20 11 10
res_idx 9 0 20 12 10
10 1 20 0 10
11 1 20 1 10
12 1 20 2 10
13 1 20 3 10
14 1 20 4 10
15 1 20 8 10
16 1 20 9 10
17 1 20 10 10
18 1 20 11 10
19 1 20 12 10
20 0 20 0 10
21 0 20 1 10
22 0 20 2 10
23 0 20 3 10
24 0 20 4 10
25 0 20 8 10
26 0 20 9 10
27 0 20 10 10
28 0 20 11 10
29 0 20 12 10
30 1 20 0 10
31 1 20 1 10
32 1 20 2 10
33 1 20 3 10
34 1 20 4 10
35 1 20 8 10
36 1 20 9 10
37 1 20 10 10
38 1 20 11 10
39 1 20 12 10

问题

  1. 如果主板有多个CPU插槽,那么每个插槽是否必须插入同型号的CPU?

    关于这问题,查阅了很多资料,大部分资料都表明 *最好使用同型号CPU* ,但是也资料表明,有些不同的型号的CPU满足特殊要求时也是可以工作的,但是不推荐使用。
    
  2. 超线程是全局的,还是可以针对每个CPU单独开启的?

  3. socket 数量是否可以为3,5,7这样的奇数?

  4. 多socket主板,能不能只插入一块CPU?

  5. 超线程数量是否能为3,5,7这样的奇数?

  6. CPU online 表示什么?如何使CPU online或offline?