操作系统-CPU粘合

简介: 操作系统-CPU粘合

CPU性能优化


cpu粘合可以提高CPU效率


前言


提示:这里可以添加本文要记录的大概内容:

CPU孤立或者将进程/线程与cpu绑定,最直观的好处就是提高了cpu cache的命中率,从而减少内存访问损耗,提高程序的速度。在NUMA架构下,这个操作对系统运行速度的提升有较大的意义,而在SMP架构下,这个提升可能就比较小。这主要是因为两者对于cache、总线这些资源的分配使用方式不同造成的,NUMA每个cpu有自己的一套资源体系, SMP中每个核心还是需要共享这些资源的,从这个角度来看,NUMA使用cpu绑定时,每个核心可以更专注地处理一件事情,资源体系被充分使用,减少了同步的损耗。SMP由于一部分资源的共享,在进行了绑定操作后,受到的影响还是很大的。


提示:以下是本篇文章正文内容,下面案例可供参考


一、CPU绑定原理


1.1CPU核心


超线程技术

超线程技术(Hyper-Threading)是利用特殊的硬件指令,把两个逻辑内核(CPU core)模拟成两个物理芯片,让单个处理器都能使用线程级并行计算,进而兼容多线程操作系统和软件,减少了CPU的闲置时间,提高CPU的运行效率。

物理CPU是计算机主板上安装的CPU也就是主板上卡槽个数。

逻辑CPU是一颗物理CPU上的物理CPU核心,通常一颗物理CPU有多颗物理内核,即有多个逻辑CPU。如果支持Intel超线程技术(HT),可以在逻辑CPU上再分一倍数量的CPU Core。


1.1.1 linux 下CPU信息查看

在linux 下/proc 目录下可以查询到系统的很多信息


查看物理CPU个数

cat /proc/cpuinfo|grep "physical id"|sort -u|wc -l


查看每个物理CPU中core的个数(即核数)

cat /proc/cpuinfo|grep "cpu cores"|uniq


查看逻辑CPU的个数

cat /proc/cpuinfo|grep "processor"|wc -l


查看CPU的名称型号

cat /proc/cpuinfo|grep "name"|cut -f2 -d:|uniq


查看进程运行的逻辑CPU

ps -eo pid,args,psr


CPU 绑定


  • CPU绑定是对进程或线程设置相应的CPU Affinity,确保进程或线程只会在设置有相应标志位的CPU上运行,进而提高应用程序对CPU的使用效率。如果应用进程可以在多个CPU上运行,操作系统会在CPU之间频繁切换应用,引起CPU缓存失效,降低缓存的命中率,导致CPU使用效率下降。使用CPU绑定技术可以在一定程度上会避免CPU Cache失效,提升系统性能。


  • CPU affinity是一种调度属性(scheduler property),可以将一个进程绑定到一个或一组CPU上。在SMP(Symmetric

Multi-Processing对称多处理)架构下,Linux调度器(scheduler)会根据CPU affinity设置让指定进程运行在绑定的CPU上,而不会在其它CPU上运行。


  • 为了避免频繁切换进程,造成进程上下文开销,可以手动地为进程分配CPU核,避免多个进程运行在一个CPU上。


  • Linux内核进程调度器天生具有软CPU亲和性(affinity)特性,调度器会试图保持进程在相同的CPU上运行,
    即进程通常不会在处理器之间频繁迁移。


查看所有进程CPU分配情况

ps -eo pid,cmd,psr


查看进程的所有线程的CPU分配情况

ps -To 'pid,lwp,psr,cmd' -p [PID]


CPU绑定特点


  • 将进程/线程与CPU绑定,可以显著提高CPU  Cache命中率 ,从而减少内存访问损耗,提高应用性能。
  • 在NUMA架构下,CPU绑定操作对系统运行速度的提升有较大的意义,而在SMP架构下,提升可能就比较小。因为两者对于cache、总线资源的分配使用方式不同。NUMA架构下,每个CPU有自己的一套资源体系;SMP架构下,每个核需要共享资源。
  • 每个CPU核运行一个进程时,由于每个进程的资源都独立,所以CPU核心之间切换时无需考虑上下文;每个CPU核运行一个线程的时候,有时线程之间需要共享资源,所以共享资源必须从CPU的一个核心被复制到另外一个核心,造成额外开销。
  • 在内核中进程和线程是不分的都使用task_struct 结构体。


二、调试工具


2.1 taskset绑定进程

安装taskset工具

yum install util-linux

查看进程的CPU Affinity,使用-p选项指定PID,默认打印十六进制数,如果指定-cp选项打印CPU核列表。3的二进制形式是0011,对应-cp打印0和1,表示进程只能运行在CPU的第0个核和第1个核。

taskset [options] [mask] -p pid

查看指定进程的CPU Affinity

taskset -c -p pid

设置指定进程的CPU Affinity,对于孤立CPU,只有第一个CPU有效。

使用11,12,13,14,15号CPU运行进程

taskset -p mask pid
taskset -c [CPU NUMBER] -p PID

Docker容器中,孤立CPU仍然可以被使用;创建Docker容器时可以通过参数–cpuset-cpus指定容器只能使用哪些CPU,实现Docker容器内孤立CPU。


taskset -c 11,12,13,14,15 python xx.py
taskset -c 11-15 python xx.py

例子

(1)绑定进程至指定CPU

taskset -pc CPU_NUMBER  PID
taskset -p PID

查看进程的CPU Affinity

(2)进程启动时绑定至CPU

taskset -c CPU_NUMBER PROGRAM&


启动PROGRAM程序后台运行,绑定进程至CPU_NUMBER核心,

taskset -p PID

查看进程的CPU Affinity

2.2cset绑定进程

cset set --cpu CPU CPUSET NAME


定义CPU核心集合,对于独立CPU,只有第一个CPU核心有效。

cset proc --move --pid=PID,...,PID --toset=CPUSET NAME

移动多个进程到指定CPU集合


三、常用接口


3.1 设置掩码接口

CPU的掩码是采用位图方式存储的:

cpu_set_t  //是一个掩码数组,一共有1024位,每一位都可以对应一个cpu核心  
//以下宏,都是对这个掩码进行操作的。如果需要,一个进程是可以绑定多个cpu的。  
void CPU_ZERO(cpu_set_t *set);  
void CPU_SET(int cpu, cpu_set_t *set); // CPU 掩码设置 , int cpu 表示绑定的cpu核。 
void CPU_CLR(int cpu, cpu_set_t *set);  
int CPU_ISSET(int cpu, cpu_set_t *set);  
//以下是CPU核有关
sysconf(_SC_NPROCESSORS_CONF)//获取CPU核数
syscall(__NR_gettid); //系统调用后进程id

3.2 进程级别粘合

进程和CPU粘合接口:

#define _GNU_SOURCE               
#include <sched.h>  
 //设定pid 绑定的cpu,
int sched_setaffinity(pid_t pid,           //进程号,如果pid值为0,则表示指定当前进程。
          size_t cpusetsize,     //mask参数所指定数的长度,通常设定为sizeof(cpu_set_t)。
          cpu_set_t *mask);       //CPU掩码     
int sched_getaffinity(pid_t pid, size_t cpusetsize,cpu_set_t *mask);    //查看pid 绑定的cpu。  

3.3 线程级别粘合

线程和CPU粘合接口:

#define _GNU_SOURCE  
#include <pthread.h>  
int pthread_setaffinity_np(pthread_t thread,      //线程id
              size_t cpusetsize,  
                          const cpu_set_t *cpuset);  
int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize,  
                          cpu_set_t *cpuset);  

Note : 可以通过htop查看CPU绑定情况


粘合例子


提示:这里对文章进行总结:

/**
 * @brief cpu的亲缘性 cpu 做到粘合作用 进程和线程都是可以绑定的
 *  更大程度利用cpu ,多核cpu ,每个cpu上都有一个调度队列、进程粘合之后,不会发生进程切换到空闲cpu。
 * 一定程度上节省进程切换的代价
 */
//进程和线程都是可以做粘合的,进程和线程都是调用sched_setaffinity() 这个亲缘性。
//在内核中进程和线程是不分的都叫做task_struct;
#define __USE_GNU
#include <unistd.h>
#include <sched.h>
#include <sys/syscall.h>
//task_struct
void process_affinity(int num){
    //gettid()
    pid_t selfid = syscall(__NR_gettid); //系统调用后
    cpu_set_t mask;
    CPU_ZERO(&mask);
    CPU_SET(selfid%num, &mask);  //mask 位图
    sched_setaffinity(selfid, sizoef(mask), &mask);
    while(1);
}
int main(){
// 使用进程
int num = sysconf(_SC_NPROCESSORS_CONF); //cpu 数量  内核自带的_SC_NPROCESSORS_CONF
int i = 0;
pid_t pid = 0;
for (i =0; i< num/2; i++){
    pid = fork(); 
    if (pid <= (ppid_t)0){ //创建出的进程返回掉
        break;
    }
}
if (pid == 0) {
    process_affinity(num);
}
while(1) usleep(1);
}


四、孤立CPU


41、孤立CPU简介

针对CPU密集型的任务,CPU负载较高,推荐设置CPU Affinity,以提高任务执行效率,避免CPU进行上下文切换,提高CPU Cache命中率。

默认情况下,Linux内核调度器可以使用任意CPU核心,如果特定任务(进程/线程)需要独占一个CPU核心并且不想让其它任务(进程/线程)使用时,可以把指定CPU孤立出来,不让其它进程使用。


4.2、孤立CPU的特点

孤立CPU可以有效地提高孤立CPU上任务运行的实时性,在保证孤立CPU上任务运行的同时会减少了其它任务可以运行的CPU资源,因此需要对计算机CPU资源进行规划。


4.3、孤立CPU设置

Linux Kernel中isolcpus启动参数用于在SMP均衡调度算法中将一个或多个CPU孤立出来,通过CPU Affinity设置将指定进程置于孤立CPU运行。

isolcpus= cpu_number [, cpu_number ,...]

(1)修改grub配置文件

默认grub配置为/etc/default/grub,GRUB_CMDLINE_LINUX值中加入isolcpus=11,12,13,14,15,所有CPU核心必须用逗号进行分隔,不支持区域范围。


GRUB_CMDLINE_LINUX="isolcpus=1,2 crashkernel=auto rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet"

(2)更新grub

重新生成grub引导文件/boot/grub/grub.cfg,重启系统生效。

update-grub
update-grub2
grub-mkconfig -o /boot/grub/grub.cfg

一旦Linux Kernel使用isolcpus参数启动,Linux Kernel任务均衡调度器不会再将进程调度给指定CPU核心,用户通常需要使用taskset或cset命令将进程绑定到CPU核心。


参考


CPU绑定

目录
相关文章
|
4月前
|
Linux 调度
部署02-我们一般接触的是Mos和Wimdows这两款操作系统,很少接触到Linux,操作系统的概述,硬件是由计算机系统中由电子和机械,光电元件所组成的,CPU,内存,硬盘,软件是用户与计算机接口之间
部署02-我们一般接触的是Mos和Wimdows这两款操作系统,很少接触到Linux,操作系统的概述,硬件是由计算机系统中由电子和机械,光电元件所组成的,CPU,内存,硬盘,软件是用户与计算机接口之间
|
5月前
|
虚拟化 iOS开发 MacOS
客户机操作系统已禁用 CPU。请关闭或重置虚拟机。解决方法
客户机操作系统已禁用 CPU。请关闭或重置虚拟机。解决方法
2580 0
|
6月前
|
存储 缓存 PHP
阿里云服务器实例、CPU内存、带宽、操作系统选择参考
对于使用阿里云服务器的用户来说,云服务器的选择和使用非常重要,如果实例、内存、CPU、带宽等配置选择错误,可能会影响到自己业务在云服务器上的计算性能及后期运营状况,本文为大家介绍一下阿里云服务器实例、CPU内存、带宽、操作系统的选择注意事项,以供参考。
阿里云服务器实例、CPU内存、带宽、操作系统选择参考
|
6月前
|
存储 算法 Linux
【计算机操作系统】深入探究CPU,PCB和进程工作原理
【计算机操作系统】深入探究CPU,PCB和进程工作原理
178 1
|
6月前
|
存储 SQL 缓存
手写操作系统(5)——CPU工作模式与虚拟地址(下)
手写操作系统(5)——CPU工作模式与虚拟地址
54 0
|
6月前
|
存储 缓存 Linux
手写操作系统(5)——CPU工作模式与虚拟地址(上)
手写操作系统(5)——CPU工作模式与虚拟地址
70 0
|
6月前
|
Linux
Linux操作系统调优相关工具(一)查看CPU负载相关工具 找出系统中使用CPU最多的进程?
Linux操作系统调优相关工具(一)查看CPU负载相关工具 找出系统中使用CPU最多的进程?
60 0
|
6月前
|
算法 网络协议 调度
操作系统 -- CPU调度
操作系统 -- CPU调度
63 0
|
6月前
|
资源调度 调度 UED
CPU执行系统调用时发生中断,操作系统还能切回中断前的系统调用继续执行吗?
系统调用服务例程在执行过程中,通常不会被中断。系统调用服务例程的执行是一个原子操作,即在执行期间不会被中断。这是为了确保在系统调用服务例程执行期间对内核数据结构的一致性和完整性。
|
6月前
|
存储
手写操作系统 - CPU段页门
手写操作系统 - CPU段页门