Linux cpu 亲缘性 绑核
前言
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_conf和get_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_ALLOC与CPU_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 亲缘性 绑核的更多相关文章
- Linux CPU亲缘性详解
前言 在淘宝开源自己基于nginx打造的tegine服务器的时候,有这么一项特性引起了笔者的兴趣.“自动根据CPU数目设置进程个数和绑定CPU亲缘性”.当时笔者对CPU亲缘性没有任何概念,当时作者只是 ...
- KVM虚拟机cpu资源限制和vcpu亲缘性绑定
前言 KVM中添加的实例存在资源分布不均的情况,这样如果有消耗资源的实例会影响到其他实例的服务正常运行,所以给kvm做资源限制是很有必要的,下面记录一下在centos7中KVM环境下使用cgroup限 ...
- CPU affinity 进程和线程的亲缘性
设置Processor Affinity 作用: 1.进程和线程的亲缘性(affinity),使进程或线程在指定的CPU(核)上运行.(比如程序A,在第4个核心上运行) 2.设置进程 或者 线程, 使 ...
- 【记录一个问题】android ndk下设置线程的亲缘性,总有两个核无法设置成功
参考了这篇文章:https://blog.csdn.net/lanyzh0909/article/details/50404664 大体的代码如下: #include <pthread.h> ...
- Linux操作系统实时性分析
1. 概述 选择一个合适的嵌入式操作系统,可以考虑以下几个因素: 第一是应用.如果你想开发的嵌入式设备是一个和网络应用密切相关或者就是一个网络设备,那么你应该选择用嵌入式Linux或者uCLinux ...
- 查看线程linux cpu使用率
Linux下如何查看高CPU占用率线程 LINUX CPU利用率计算 转 http://www.cnblogs.com/lidabo/p/4738113.html目录(?)[-] proc文件系统 p ...
- Windows内核之线程的调度,优先级,亲缘性
1 调度 Windows不是实时操作系统,它是抢占式多线程操作系统.在如果全部优先级同样的情况下,CPU对线程的调度原则是每隔20m就会切换到下一个线程,依据Context中的IP和SP来接着运行上次 ...
- Linux CPU数量判断,通过/proc/cpuinfo.
Linux CPU数量判断,通过/proc/cpuinfo. 相同 physical id :决定一个物理处理器 如果“siblings”和“cpu cores”一致,则说明不支持超线程,或者超线程未 ...
- SetThreadAffinityMask设置线程亲缘性
The SetThreadAffinityMask function sets a processor affinity mask for the specified thread. DWORD_PT ...
- 理解Linux CPU负载和 CPU使用率
CPU负载和 CPU使用率 这两个从一定程度上都可以反映一台机器的繁忙程度. cpu使用率反映的是当前cpu的繁忙程度,忽高忽低的原因在于占用cpu处理时间的进程可能处于io等待状态但却还未释放进入w ...
随机推荐
- 2020-11-16:手写代码:leetcode第406题。假设有打乱顺序的一群人站成一个队列。 每个人由一个整数对(h, k)表示,其中h是这个人的身高,k是排在这个人前面且身高大于或等于h的人数。 编写一个算法来重建这个队列。
福哥答案2020-11-16: ①排序.按照[身高]降序排列.如果[身高]一样,按照[人数]升序排列.②插入.遍历这个队列,按照[人数]插入相应位置. 采用leetcode里的代码,golang代码如 ...
- 2021-02-21:手写代码:高性能路由,也就是一个字符串和多个匹配串进行模糊匹配。一个数组arr里是["*a*","moonfdd"],字符串"moonfdd"能匹配到,理由是arr里有。字符串"xayy"也能匹配到,理由是arr里的"*a*",第1个星对应"x",第2个星对应"yy"。
2021-02-21:手写代码:高性能路由,也就是一个字符串和多个匹配串进行模糊匹配.一个数组arr里是["a","moonfdd"],字符串"moo ...
- mac系统下,docker安装kibana报错,manifest for kibana:latest not found: manifest unknown: manifest unknown
1.问题描述:mac系统下,docker安装kibana报错,manifest for kibana:latest not found: manifest unknown: manifest unkn ...
- Accurate SerDes LineRate
测试现象:(单板A板载7A series,单板B板载7K series) 1. 单板A板载2个type C接口,通过线缆自环,GTP near-end loopback, OK. 2. 2块单板A,使 ...
- c#构建具有用户认证与管理的socks5代理服务端
Socks 协议是一种代理 (Proxy) 协议, 例如我们所熟知的 Shdowsocks 便是 Socks 协议的一个典型应用程序, Socks 协议有多个版本, 目前最新的版本为 5, 其协议标准 ...
- 代码随想录算法训练营Day6 哈希表|242.有效的字母异位词 349.两个数组的交集 202.快乐数 1.两数之和
哈希表理论基础 哈希表 哈希表(Hash tble)是根据关键码的值而进行直接访问的数据结构. 哈希表简单来说是数组,当我们遇到了要快速判断一个元素是否出现在集合里的时候,就要考虑哈希表. 哈希表中的 ...
- 基于php的外卖订餐网站(php+mysql)
介绍 一个基于php的外卖订餐网站,包括前端和后台. 效果演示 http://101.43.124.118:8001/admin 源码地址 https://github.com/geeeeeeeek/ ...
- 重新温习git
在本地文件夹创建项目,使用git bash here,然后使用git clone[url]命令克隆,提示权限不足, 这是需要ssh重置了 1.删除原有.ssh文件下的known_hosts 2.设置用 ...
- C#语言async, await 简单介绍与实例(入门级)
本文介绍异步编程的基本思想和语法.在程序处理里,程序基本上有两种处理方式:同步和异步.对于有些新手,甚至认为"同步"是同时进行的意思,这显然是错误的. 同步的基本意思是:程序一个个 ...
- 【WALT】scale_exec_time() 代码详解
@ 目录 [WALT]scale_exec_time() 代码详解 代码展示 代码逻辑: 为什么归一化? ⑴ 将 CPU cycles 转换为 CPU 当前频率 ⑵ 归一化 delta [WALT]s ...