首页 > 系统相关 >Linux性能优化篇-了解CPU上下文切换

Linux性能优化篇-了解CPU上下文切换

时间:2023-04-25 16:00:43浏览次数:35  
标签:中断 CPU 切换 Linux 进程 上下文 cpu


 

我们了解到导致平均负载,有可能是以下几种方面:

  1. CPU密集型(造成cpu利用率升高,可以理解)
  2. I/O密集型(io和cpu互斥的,也造成cpu利用率增高-不可中断进程的
  3. 大量进程(???)

根据平均负载的解释,单位时间内的处于可运行的进程和不可中断进程的进程数

System load averages is the average number of processes that are either in a runnable or uninterruptable state. A process in uninterruptable state is waiting for some I/O access, eg waiting for disk

所以我们会比较好了解CPU密集型,需要大量计算资源,会非常消耗cpu,I/O密集型需要等待I/O,会有大量的不可中断进程,

那么大量进程的情况下是如何导致平均负载升高的?

存在大量的进程竞争cpu,也就是存在大量的可运行进程,但是我们都知道cpu一个时间段其实只能运行一个进程,其他的进程也都只是在等待,并不会大量耗尽cpu资源的情况,而是cpu按照时间片给大量进程运行,所以可以想象在不停的切换不停的进程的情况下是不是也在消耗cpu资源能力,也就是我们今天要说的cpu上下文切换

Linux是一个多用户用任务的操作系统,他支持远远大于cpu的进程数运行,而cpu每次却只能运行一个任务,所以其实这些任务其实并不是在同时运行,整个过程是cpu轮流运行任务,给用户带来的假象。而当一个任务需要运行前,cpu需要知道从那里加载,从哪里开始运行,也就是系统需要事先设置好cpu寄存器和程序计数器。

  1. cpu寄存器: cpu内置的容量小,但是速度极快的内存。
  2. 程序计数器: 用来存储cpu正在执行的指令位置,或者即将执行的下一条指令位置。

它们是CPU在运行任何任务前,必须依赖的,所以也被称为CPU上下文。

所以根据上下文的了解,所谓的上下文切换:

  1. 把前一个任务的CPU上下文保存下来
  2. 找到并加载新任务的上下文
  3. 切换到新的cpu寄存器和程序计数器最后跳到程序计数器所指的新位置,开始运行新任务。

保存下来的上下文会存储在内核,并在任务重新调度时再加载进去,这样任务不受影响,任务看起来来也是连续运行的。

根据任务的不同,CPU上下文切换可以分几种不同场景:

  •  
  • 进程上下文切换
  • 线程上下文切换
  • 中断上下文切换
  •  

进程上下文切换

Linux分为内核空间和用户空间:

Linux性能优化篇-了解CPU上下文切换_系统调用

 

所以根据内核空间划分,一个进程可以被称为进程的用户态和进程的内核态,

当一个系统调用发生市必然会发生CPU上下文切换的,

比如我们加载存在磁盘里的一个文件,我们触发的指令是进程的用户态,而我们需要操作磁盘就需要系统调用陷入内核态,而我们原先的用户态就需要保存起来,执行内核态的指令,加载完数据就需要恢复用户态,继续运行进程,

 

Linux性能优化篇-了解CPU上下文切换_上下文切换_02

所以可以知道一次系统调用会发生两次CPU上下文切换。

这里说的系统调用和进程上下文切换又是不同的:

  1. 进程上下文切换是指从一个进程切换到另一个进程
  2. 系统调用始终在一个进程中运行

所以系统调用还是被称为特权模式调用,而不是上下文切换,但是系统调用导致的cpu上下文切换还是不可避免。

Linux性能优化篇-了解CPU上下文切换_上下文切换_03

Linux性能优化篇-了解CPU上下文切换_上下文切换_04

 

 

那么进程的上下文切换和系统调用存在什么关系?

进程是需要系统内核来管理和调度的,进程的上下文切换只能发生在内核态,

所以进程的上下文不仅包括虚拟内存、栈、全局变量等用户空间资源,还有内核堆栈、寄存器等内核空间状态

所以进程的上下文切换和系统调用(软中断)多了一个保存用户空间和恢复用户空间。

进程上下文切换过程:

  1. 接受切换信号,挂起进程,记录当前的进程的虚拟内存、栈等资源存储
  2. 将这个进程在CPU的上下文状态存储
  3. 然后检索下一个进程的CPU的上下文
  4. 加载到CPU的寄存器中恢复
  5. 还需要刷新进程保存的虚拟内存和用户栈
  6. 最后跳转到程序计数器所指向的位置,恢复进程运行

而保存上下文和恢复上下文过程不是免费的,大概每次上下文切换会花费几十纳秒到数微妙之间,当大量进程时,这个cpu上下文切换是相当可观的,会花费大量时间在保存和恢复cpu上下文和用户空间状态,cpu分配给进程的时间片是一定的,导致cpu实际运行进程时间大大减少,而当时间片用完,进程必须挂起,这也是导致平均负载升高的一个因素。

什么时候需要进行进程上下文切换?

Linux会为每个cpu都维护一个就绪队列,也就是进程状态为R状态的的进程,最理想状态是之前的进程完成,cpu得到释放,下一个进程得到cpu使用,但是实际情况是不同的。

  1. 为了保证所有进程得到公平调度,CPU时间被划分一段段时间片,这些时间片轮流分给进程,当时间片耗尽,进程会被挂起,等待下一次分配cpu时间片。
  2. 进程运行的系统资源不足,比如内存不足,进程必须得倒资源满足才可以运行,这个时候会被挂起,系统会调度其他可运行的进程。
  3. 当进程通过睡眠函数主动挂起,会重新调度。
  4. 当有高优先级的进程运行时,为保障高优先级运行,当前进程会被挂起,由高优先级进程运行。
  5. 发生硬件中断,cpu上的进程会被挂起,而由内核中的中断服务运行。

线程上下文切换

线程和进程的最大区别在于,线程是调度的基本单位,而进程则是资源拥有的基本单位,说白了,内核中的任务调度,调度的对象就是线程,而进程给线程提供虚拟内存、全局变量等资源。

进程与线程的比较:

  1. 当进程只有一个线程的时候,进程就等于线程
  2. 当进程由多个线程的时候,这些线程会共享相同的虚拟内存与全局变量等资源,这些在上下文切换的时候不需要修改
  3. 线程也是有私有数据的,这些数据在上下文切换的时候是需要保存的

所以这里也可以看出,相对于比较多进程与多线程,

多线程间的切换会比多进程间的切换消耗更少的资源。

中断上下文切换

  • 中断
  1. 软中断可以触发内核执行 We know that we can trigger the kernel to execute by generating a software interrupt.
  2. int 指令可以产生软中断

Kernel-side: int $0x80 entry point

Linux性能优化篇-了解CPU上下文切换_上下文切换_05

 

为了快速响应硬件事件,中断处理会打断进程的正常调度和执行,转而执行调用中断处理程序,响应设备事件。但是和进程的上下文不同的是,

中断上下文切换不会涉及到进程的用户态,只是需要内核态中断程序执行必需的状态,并且对于一个cpu来说,中断处理比进程拥有更高的优先级。

怎么查看系统上下文切换情况

过多的cpu上下文切换会导致花费大量的时间消耗在寄存器、内核栈及虚拟内存的保存与恢复中,缩短cpu在规定时间片内真正运行的时间,导致系统性能大幅下降。

vmstat可以用来分析系统内存使用情况,也可以用来分析cpu上下文切换和中断的次数。


 


  1. r: Running or Runnable Task 是就绪队列的长度,也就是正在运行和等待CPU的进程数
  2. b: Blocked Task 处于不可中断睡眠状态的进程数
  3. cs: Context switch 是每秒上下文切换的次数
  4. in: Interrupt 则是每秒中断的次数

vmstat可以给出总体的上下文切换情况,如果想要查看每个进程的详细情况,

需要pidstat来查看:


 


  1. cswch: 表示每秒自愿上下文切换的次数
  2. nvcswch: 表示每秒非自愿上下文切换

这两种概念意味着不同的性能问题:

  • 自愿上下文切换,是指进程无法获取所需资源,导致的上下文切换,如I/O,内存不足等问题,就会发生大量的自愿上下文切换。
  • 非自愿上下文切换,是指进程由于时间片已到,被系统强制调度,而发生的上下文切换,比如大量进程争抢cpu,会发生大量非自愿上下文切换。

上下文切换频率多少才算合适

使用sysbench模拟多线程调度瓶颈:


 


查看vmstat:


 


cs(上下文切换)突然增大到300多万,同时观测到r增大到9,远远超过了操作系统的2核,us(user)和sy(system)这两列cpu的使用率开始突增,cpu主要被内核空间占有,in列也开始增加一倍,说明中断也是一个原因。

我们从vmstat大体可以看出cpu上下文切换和中断,并且存在多个进程竞争情况,内核空间异常繁忙,接下来我们需要分析原因,需要继续分析:


 


很明显看出来cpu使用率升高是sysbench导致的,而上下文切换则是其他进程,包括非自愿上下文切换最高的pidstat,但是我们会发现自愿上下文切换比vmstat来说的300多万来说小太多了,我们需要考虑线程问题。


 


还有我们要如何查看中断突然增大:

watch -d cat /proc/interrupts


 


Rescheduling interrupts are the Linux kernel's way to wake-up an idle CPU-core to schedule a thread on it. On SMP systems, this is often done by the scheduler in a effort to spread the load across multiple CPU-cores. 重新安排中断是Linux内核唤醒空闲CPU核心以在其上安排线程的方法.在SMP系统上,这通常由调度程序完成,以便将负载分散到多个CPU核心 Function call interrupts:: software-interrupts to 软中断

所以回到上下文切换多少合适,这个数值还是取决于cpu性能,如果想要系统比较稳定,这个值可以尽量控制在几百到一万之间,如果超过一万或者指数级增量,一般都是出现性能问题。

总结:

sysbench是一款开源的多线程性能测试工具,可以执行CPU/内存/线程/IO/数据库等方面的性能测试

  • 自愿上下文切换变多,说明进程在等待资源,可能I/O等其他问题
  • 非自愿上下文切换变多,说明进程被强制调度,争抢cpu,cpu是瓶颈
  • 中断次数增多,说明cpu被中断处理程序占用,要通过/proc/interrupts文件来分析具体的中断类


标签:中断,CPU,切换,Linux,进程,上下文,cpu
From: https://blog.51cto.com/u_16081664/6224236

相关文章

  • linux之dlopen、dlsym和dlclose使用和举例
     之前用过这三个函数一直没时间整理一下。今天抽时间整理一下。1、函数简介dlopen基本定义功能:打开一个动态链接库 包含头文件: #include<dlfcn.h> 函数定义: void*dlopen(constchar*pathname,intmode); 函数描述: 在dlopen的()函数以指......
  • linux中修改文件常用vim命令
    linux中修改文件常用vim命令个人博客地址:https://note.raokun.top拥抱ChatGPT,国内访问网站:https://www.playchat.top按键作用含义i在当前字符前插入(记忆:insert)I在光标所在行的行首插入a在当前字符后插入(记忆:afterinsert)A在光标所在行的行尾插入......
  • RHEL8常用命令-Linux就该这么学2
       首先介绍系统内核和Shell终端的关系与作用,然后介绍Bash解释器的4大优势并学习Linux命令的执行方法。经验丰富的运维人员能够通过合理地组合命令,来更精准地满足工作需求,还可以尽可能地降低系统资源消耗。   本章选出常用的数十个Linux命令,它们与系统工作......
  • Linux解压RAR文件
    首先说明1、linux中常常会遇到一些rar结尾的文件包,靠linux本身的命令是无法实现解压rar结尾的文件夹的,需要安装rar的压缩软件才可以。2、要将服务器的账号切换为root账户,否则安装会出错。1、下载linux版本的rar软件访问RARLAB官网下载最新的、适用于自己的linux版本的rar软件......
  • Linux VFS中write系统调用实现原理
    目录用户空间的write函数在内核里面的服务例程为sys_write.1Vfs_write函数实现原理...2 WORD里面的目录复制过来似乎不能直接用。。还是放在这里当主线看吧..用户空间的write函数在内核里面的服务例程为sys_writeroot@syslab~]#grepwrite/usr/include/asm/unistd......
  • 处理Linux 终端中文显示乱码问题
    问题详情:中文命名的文件或者文件夹显示?号或者□,无法正常显示文件名1、查看是否已安装中文字体#查看已安装的中文字体fc-list:lang=zh#查看已安装的中文字体并排序fc-list:lang=zh-cn|sort2、安装字体库yum-yinstallfontconfig3、添加中文字体,建立存储中文......
  • rust交叉编译配置:windows上编译linux可执行程序
    rust交叉编译配置:windows上编译linux可执行程序简述交叉编译大概指在在一种计算机环境中运行的编译程序,能编译出在另外一种环境下运行的代码.本次,我们配置的是在windows上编译出在linux上运行的rust可执行程序.我们在安装rust之后,默认会安装跟机器环境搭配的编译相关工具.......
  • xshell 传输文件后,Linux终端显示乱码
    原因:XSHELL与Linux编码设置不一致终端:xshell: 解决方法:设置为一致即可 ......
  • Linux常用技巧(十三)
    1、点亮指定硬盘:定位,磁盘闪灯/opt/MegaRAID/MegaCli/MegaCli64-PdLocate-start-physdrv[E:S]-a0/opt/MegaRAID/MegaCli/MegaCli64-PdLocate-stop-physdrv[E:S]-a02、查看证书过期时间echo|openssls_client-servername${domain}-connect${domain}:4432>/dev/null|......
  • 10 iozone Examples for Disk I/O Performance Measurement on Linux
    https://www.thegeekstuff.com/2011/05/iozone-examples/ Aswediscussedinour Linuxperformancemonitoringintroduction article,measuringIOsubsystemperformanceisveryimportant.Ifsomeoneiscomplainingthatadatabase(oranyapplication)running......