前言

https://www.cnblogs.com/studywithallofyou/p/17435497.html

https://www.cnblogs.com/studywithallofyou/p/16695550.html

上面的文章提到了一些相关的知识,本篇单独针对CPU进行详细讲解。

CPU构造

CPU Central Processing Unit CPU Package

这个一般指的是整个CPU,包括包装运行单元,控制单元,缓冲等。

比如下面Intel 80486DX2正反面

正面是一个金属壳,用于散热

反面是很多针脚,用于传递数据



CPU Socket CPU插槽

这个就是指主板上有几个可以插CPU的地方,比如下面,就有两个

Non-uniform memory access NUMA Node

为了处理多CPU访问内存的问题,提出了NUMA架构,就是把不同的CPU做区分,分配不同的内存通道。Node访问自己所属的内存(也叫local)速度比较快,访问另一个Node的内存相对就慢一些。

正常情况NUMA Node与CPU Socket数量是一致的,一个插槽上插一个CPU,一个CPU分配一个NUMA Node。不过也有不一致的情况。

UMA

计算机一开始的架构是UMA:多个Processor使用同一个bus总线访问内存,大家是平等的。后来随着CPU核心增多,总线成为了瓶颈,就把Processor分组,各自访问一块内存,变成了NUMA(非一致性内存访问)。

NUMA与MySQL

Linux默认会启用NUMA,让程序尽可能申请local内存,如果超过了local内存,就会频繁的swap。

如果是占用内存比较大的程序,需要确保开启NUMA后,local内存足够,不然会导致性能抖动或者下降。

如果MySQL使用内存大于其占用的Node的解决方案:

  • 设置绑定策略,让MySQL可以从使用所有内存
  • MySQL也有相关配置,应对这个场景。需要确认使用版本是否有该功能,如果没有,需要下载最新的,或者编译对应版本,在编译是开启对NUMA的支持。

Processor Die CPU Die 处理器芯片

Die就是指从晶圆上切下来的一个个小方块,后续通过光刻机,刻上晶体管,形成core。

一个Die上可以拥有多个core。

Processor core

Processor core是一个独立的单元,可以与其他core并行运算。

Integrated Circuit IC 集成电路

一个或多个Die加上一些缓存、集成显卡组成一块集成电路

Printed Circuit Board PCB 印刷电路板

集成电路被安装在印刷电路版上。印刷电路板和外壳等组成一块CPU。

如下图,这是一块CPU,外面绿色的是印刷电路板,中间两个突起的方块是Die,一个Die有两个Core,那么这个CPU就是双核四核心(我们经常说的)。

一个Die打开如下图,中间分开,上下对称,用晶体管实现了两个core

总结

由于CPU的设计,对不同资源做了区分,所以在高性能程序开发中,需要配置,保证最大化利用系统资源。

让一个进程绑定在同一个core或者同一个Node下的core上,保证CPU缓存命中率,避免使用remote memory,避免上下文切换。

具体使用思路:把需要高性能运行的进程绑定到一个(一组core)上,把其他进程绑定到其他core上,避免其他进程在高性能进程占用的core上运行,使得高性能进程绑定的core只运行一个进程,避免其他进程打扰,避免缓存丢失,避免上下文切换,提高性能。

https://en.wikipedia.org/wiki/Central_processing_unit

https://www.cc.ntu.edu.tw/chinese/epaper/0015/20101220_1508.htm

https://superuser.com/questions/324284/what-is-meant-by-the-terms-cpu-core-die-and-package

https://en.wikipedia.org/wiki/Die_(integrated_circuit)

查看cpu信息

lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 12 core个数
On-line CPU(s) list: 0-11 在线core个数
Thread(s) per core: 1 每个物理core可以有几个thread。是否可以多个任务并发进行。逻辑核。用指令把一个物理core再分成两个或多个并发运行,提高使用率。
Core(s) per socket: 6 每个插槽上的cpu有几个core
Socket(s): 2 有几个插槽,主板上插了几块cpu
NUMA node(s): 2 有几个node,一般一个socket分成一个node
Vendor ID: GenuineIntel
CPU family: 6
Model: 45
Stepping: 7
CPU MHz: 1200.000
BogoMIPS: 3999.45
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 15360K
NUMA node0 CPU(s): 0-5 每个node上core编号
NUMA node1 CPU(s): 6-11

查看numa内存分配

numactl --hardware
available: 2 nodes (0-1) 两个noma node,0和1
node 0 cpus: 0 1 2 3 4 5 node0包含0 1 2 3 4 5core
node 0 size: 8162 MB node0内存local内存大小
node 0 free: 1855 MB
node 1 cpus: 6 7 8 9 10 11
node 1 size: 8192 MB
node 1 free: 4611 MB
node distances: node和local内存/remote内存距离关系
node 0 1
0: 10 20 node0访问node0的内存是10,访问node1的内存是20(性能下降一倍)
1: 20 10 node1访问node0的内存是20,访问node1的内存是10

libc

获取系统CPU核心数

sysconf

       #include <unistd.h>

       long sysconf(int name);
- _SC_NPROCESSORS_CONF
The number of processors configured. See also
get_nprocs_conf(3). - _SC_NPROCESSORS_ONLN
The number of processors currently online (available).
See also get_nprocs(3).

一个是获取全部的CPU核心数,一个是获取可用的(online)核心数。也有专门的APIget_nprocs_confget_nprocs

https://man7.org/linux/man-pages/man3/sysconf.3.html

get_nprocs get_nprocs_conf

       #include <sys/sysinfo.h>

       int get_nprocs(void);
int get_nprocs_conf(void);

https://man7.org/linux/man-pages/man3/get_nprocs_conf.3.html

mask CPU核心表示方法

linux用位掩码(bitmask)表示每个core

0001 第一个core[core0](core编号从0开始)

0011 第一个和第二个core[core0 core1]

1000 0001 第一个和第八个core[core0 core7]

动态申请CPU core个数

cpu_set_t *CPU_ALLOC(int num_cpus);
Allocate a CPU set large enough to hold CPUs in the range 0 to num_cpus-1.
申请保存指定cpu core个数(num_cpus)的mask空间。 size_t CPU_ALLOC_SIZE(int num_cpus);
Return the size in bytes of the CPU set that would be needed to hold CPUs in the range 0 to num_cpus-1. This macro provides the value that can be used for the setsize argument in the CPU_*_S() macros
计算指定cpu core个数(num_cpus)的mask的长度。 void CPU_FREE(cpu_set_t *set);
Free a CPU set previously allocated by CPU_ALLOC().

保存core mask的结构体cpu_set_t默认是unsigned long,有128个,可以表示1024个core。正常情况足够了,如果core大于1024,需要动态申请。具体系统的core数量,通过上面的api获取。CPU_ALLOCCPU_ALLOC_SIZE中的参数num_cpus必须一致,不然在后续使用中不匹配,导致报错。

获取和设置cpu亲缘性

#include <sched.h>

int sched_setaffinity(pid_t pid, size_t cpusetsize,
cpu_set_t *mask); int sched_getaffinity(pid_t pid, size_t cpusetsize,
cpu_set_t *mask);

如果pid为0,就表示当前进程。

获取cpu亲缘性

    cpu_set_t cpuset;
CPU_ZERO(&cpuset);
sched_getaffinity(0, sizeof(cpuset), &cpuset);

cpuset中保存了当前进程使用的cpu core。

设置cpu亲缘性

    cpu_set_t set;
CPU_ZERO(&set); //把core0和core2绑定到当前进程
CPU_SET(0, &set);
CPU_SET(2, &set);
sched_setaffinity(0, sizeof(set), &set);

https://man7.org/linux/man-pages/man2/sched_setaffinity.2.html

https://man7.org/linux/man-pages/man3/CPU_COUNT.3.html

https://linux.die.net/man/3/cpu_set

https://linux.die.net/man/7/cpuset

taskset

       #启动一个程序,并且绑定到mask指定的core上
taskset [options] mask command [argument...] #不加mask,表示获取pid指定程序的mask;增加mask,表示设置pid指定程序的mask
taskset [options] -p [mask] pid #mask,如果不特殊说明,都是16进制,--cpu-list按照core编号指定,如下都是正确的
0x00000001
is processor #0, 0x00000003
is processors #0 and #1, FFFFFFFF
is processors #0 through #31, 0x32
is processors #1, #4, and #5, --cpu-list 0-2,6
is processors #0, #1, #2, and #6. --cpu-list 0-10:2
is processors #0, #2, #4, #6, #8 and #10. The suffix ":N"
specifies stride in the range, for example 0-10:3 is
interpreted as 0,3,6,9 list.

获取mask

taskset -p 15948
pid 15948's current affinity mask: 2

为启动进程设置mask

taskset -c 0 ls

为指定进程id设置mask

taskset -pc 0,1,2 15948

https://www.man7.org/linux/man-pages/man1/taskset.1.html

Linux cpu 亲缘性 绑核的更多相关文章

  1. Linux CPU亲缘性详解

    前言 在淘宝开源自己基于nginx打造的tegine服务器的时候,有这么一项特性引起了笔者的兴趣.“自动根据CPU数目设置进程个数和绑定CPU亲缘性”.当时笔者对CPU亲缘性没有任何概念,当时作者只是 ...

  2. KVM虚拟机cpu资源限制和vcpu亲缘性绑定

    前言 KVM中添加的实例存在资源分布不均的情况,这样如果有消耗资源的实例会影响到其他实例的服务正常运行,所以给kvm做资源限制是很有必要的,下面记录一下在centos7中KVM环境下使用cgroup限 ...

  3. CPU affinity 进程和线程的亲缘性

    设置Processor Affinity 作用: 1.进程和线程的亲缘性(affinity),使进程或线程在指定的CPU(核)上运行.(比如程序A,在第4个核心上运行) 2.设置进程 或者 线程, 使 ...

  4. 【记录一个问题】android ndk下设置线程的亲缘性,总有两个核无法设置成功

    参考了这篇文章:https://blog.csdn.net/lanyzh0909/article/details/50404664 大体的代码如下: #include <pthread.h> ...

  5. Linux操作系统实时性分析

    1. 概述 选择一个合适的嵌入式操作系统,可以考虑以下几个因素:  第一是应用.如果你想开发的嵌入式设备是一个和网络应用密切相关或者就是一个网络设备,那么你应该选择用嵌入式Linux或者uCLinux ...

  6. 查看线程linux cpu使用率

    Linux下如何查看高CPU占用率线程 LINUX CPU利用率计算 转 http://www.cnblogs.com/lidabo/p/4738113.html目录(?)[-] proc文件系统 p ...

  7. Windows内核之线程的调度,优先级,亲缘性

    1 调度 Windows不是实时操作系统,它是抢占式多线程操作系统.在如果全部优先级同样的情况下,CPU对线程的调度原则是每隔20m就会切换到下一个线程,依据Context中的IP和SP来接着运行上次 ...

  8. Linux CPU数量判断,通过/proc/cpuinfo.

    Linux CPU数量判断,通过/proc/cpuinfo. 相同 physical id :决定一个物理处理器 如果“siblings”和“cpu cores”一致,则说明不支持超线程,或者超线程未 ...

  9. SetThreadAffinityMask设置线程亲缘性

    The SetThreadAffinityMask function sets a processor affinity mask for the specified thread. DWORD_PT ...

  10. 理解Linux CPU负载和 CPU使用率

    CPU负载和 CPU使用率 这两个从一定程度上都可以反映一台机器的繁忙程度. cpu使用率反映的是当前cpu的繁忙程度,忽高忽低的原因在于占用cpu处理时间的进程可能处于io等待状态但却还未释放进入w ...

随机推荐

  1. java设计模式【抽象工厂模式】

    java设计模式[抽象工厂模式] 抽象工厂模式 抽象工厂模式是对简单工厂模式的一个变种,它允许通过一个统一的接口来创建不同的产品实例,而无需指定具体的子类.在这个模式中,我们只关心产品的抽象接口,而将 ...

  2. 【.NET】C#/.NET新建项目sln,增加src和test文件夹问题和解决方案

    ​ 问题介绍 经常逛github找优秀的.NET项目看,看到github上的项目的层级有src test,sln放在外层.如下图: 发现自己再Visaul Studio新建的项目即使添加了src和te ...

  3. 向量数据库Pinecone,治疗ChatGPT幻觉的药方?

    大白话了解新鲜事,今天讲讲以Pinecone为代表的向量数据库.向量数据库Pinecone一夜爆火,4月27日B轮拿到了1亿美元的融资,估值达到7.5亿美元,一个2021年刚刚推出的数据库产品,火爆背 ...

  4. .cur 图片加载提示 You may need an appropriate loader to handle this file type

    最近一个gis 项目需要加载一个.cur的图标,但是编译时提示 You may need an appropriate loader to handle this file type, current ...

  5. Kubernetes 研究笔记

    Kubernetes 研究笔记 在接下来的这篇笔记中,我将会介绍 Kubernetes 这一强大的容器编排工具,并学习其基本使用方法.该笔记将会被存储在https://github.com/owlma ...

  6. hvv蓝初面试常见漏洞问题(下)

    hvv蓝初面试常见漏洞问题(上) 6.ssrf 服务端伪造请求 原理 服务端提供了向其他服务器应用获取数据的功能,而没有对目标地址做任何过滤和限制.攻击者进而利用其对内部资源进行攻击.(通俗来说:就是 ...

  7. 【Python&GIS】GDAL栅格转面&计算矢量面积

            GDAL(Geospatial Data Abstraction Library)是一个在X/MIT许可协议下的开源栅格空间数据转换库.它利用抽象数据模型来表达所支持的各种文件格式.它 ...

  8. Kali Linux的目录结构

    Linux目录和Windows目录有着很大的不同,Linux目录类似一个树,最顶层是其根目录,如下图: kali Linux 目录结构 bin目录 存放二进制可执行文件(如我们常用的 ls ping ...

  9. 用XmlSerializer.Deserialize将XML转实体遇到的问题

    1.命名空间的问题 1.1 XML示例: 1.2 反序列化代码: 点击查看源代码 ``` public static object DeserializeFromXml<T>(string ...

  10. MySQL 存储引擎 InnoDB 内存结构之更改缓冲区

    更改缓冲区(Change Buffer)是一种特殊的数据结构,用于缓存不在缓冲池中的二级索引(secondary index)页的更改.可能来自于INSERT.UPDATE或DELETE操作(数据操作 ...