必须了解的Linux性能基础知识( 三 )


从上我们可以知道,系统调用是在进程内进行的,其与进程上下文切换有点不同,它不会涉及到虚拟内存等用户态资源 。所以我们通常称系统调用为一种特权模式切换,而在系统调用用上下文切换是不可避免的,一次系统调用发生了两次上下文切换 。
进程是由内核管理和调度的,进程的上下文切换在内核态进行,故其上下文切换要比系统调用多了一步:在保存当前进程的内核状态和 CPU寄存器之前,需要先把该进程的虚拟内存、栈等用户资源保存起来 。
那么,什么时候需要进行上下文切换呢?

  • 进程的系统资源不足时,进程就会被挂起,等到资源充足时才能进行 。
  • 进程通过 sleep 睡眠函数等方法主动挂起时 。
  • 当有更高优先级的进程运行时,例如中断等,进程会被挂起,来保证高优先级进程正常运行 。
线程上下文切换我们知道,线程是调度的基本单位,而进程是资源拥有的基本单位,即内核中的任务调度实际对象是线程,进程只是给线程提供了虚拟内存等资源 。如果进程中有多个线程,则线程会共享虚拟内存等资源 。因此,对于线程上下文切换就有两种情况:
  • 前后切换线程属于同一进程,则虚拟内存等资源就不需要切换,只需要切换线程需要的私有资源 。
  • 前后切换线程属于两个进程,此时跟进程上下文切换一致 。
由此我们知道同一进程的线程上下文切换,要比进程间的上下文切换耗费更少资源,这也是多线程代替多进程的一大优势 。
中断上下文切换中断要比进程的优先级更高,其会打断进程的正常调度,因此中断程序需要更短小精悍,以便尽可能快地结束 。
中断上下文切换与进程不同,其不需要虚拟内存、全局变量等用户态资源,只需要如 CPU寄存器、硬件中断参数等内核态中断服务程序所需要的状态 。
如何查看查看系统总体的上下文切换情况可以通过 vmstat 命令,其输出格式为:
$ vmstat 1 1procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu---- rbswpdfreebuffcachesisobiboincs us sy id wa1000 1653888 1477852 6163030400011200 738 190其中,需要关注以下几个参数:
  • r (running),正在运行和等待运行的进程数 。
  • b (blocked),不可中断睡眠状态的进程数 。
  • in (interrupt),每秒中断次数 。
  • cs (context switch),每秒的上下文切换次数 。
而如果我们想要查看进程的上下文切换,可以通过 pidstat 查看,输出格式为:
# 通过参数 -w 可以查看进程每秒的上下文切换次数$ pidstat -w 1 1Linux 3.2.0-23-generic (cs)06/26/2021_x86_64_(24 CPU)03:19:25 PMPIDcswch/s nvcswch/sCommand03:19:26 PM10.850.00init03:19:26 PM30.850.00ksoftirqd/0...其中,需要关注两个参数:
  • cswch (voluntary context switch),每秒自愿上下文切换次数 。当进程无法获取资源,比如内存、IO 等资源不足时,就会发生自愿上下文切换 。
  • nvcswch (non voluntary context switch),每秒非自愿上下文切换次数 。当进程的时间片已到,比如大量进程争抢 CPU 时,就会被系统强制调度,发生非自愿上下文切换 。
如果我们想要查看线程间的上下文切换,还是可以通过 pidstat 查看,加上 -wt 参数选项,输出格式为:
$ pidstat -wt 1 1linux 3.2.0-23-generic (cs7)06/26/2021_x86_64_(24 CPU)03:34:07 PMTGIDTIDcswch/s nvcswch/sCommand03:34:07 PM2200-0.640.00flush-8:4803:34:07 PM-22000.640.00|__flush-8:4803:34:07 PM-2524136.540.00|__influxd03:34:07 PM-253726.920.00|__influxd03:34:07 PM-370112.823.21|__1_scheduler03:34:07 PM-37020.640.00|__2_scheduler03:34:07 PM-37251.280.00|__aux...多少为合理据统计,每次上下文切换需要耗费几十纳秒到数微秒的CPU时间,这个时间还是可以接受的 。但是过多的上下文切换,会把 CPU 时间都耗费在寄存器、内存栈以及虚拟内存的保存和恢复上,缩短进程真正运行的时间,导致系统性能大幅下降 。那么,我们肯定想了解,多少的 CPU上下文切换为合理情况呢?
这取决于 CPU 的性能 。如果上下文切换稳定,那么从数百到上万都是合理的 。但是当 CPU上下文切换呈数量级增大时,或者数值已超过上万次且不断增长时,就可能出现了性能问题,需要我们着重排查 。
CPU缓存命中率CPU缓存是为了协调CPU处理速度和内存访问速度之间的差距而出现的空间,可分为 L1、L2 和 L3 三级缓存 。离 CPU 核心越近,缓存的读写速度就越快,因此三级缓存的读写速度快慢分别是:L1 > L2 > L3.


推荐阅读