Linux性能指标之cpu上下文切换

警告
本文最后更新于 2022-09-01,文中内容可能已过时。
透过现象看本质 CPU上下文切换

CPU上下文切换是保证Linux系统正常工作的一个核心功能,按照不同场景,可以分为进程上下文切换、线程上下文切换和中断上下文切换。究竟怎么分析CPU上下文切换的问题。

过多的上下文切换,会把CPU时间消耗在寄存器、内核栈以及虚拟内存等数据的保存和恢复上,缩短进程真正运行的时间,成了系统性能大幅下降的一个元凶。

既然上下文切换对系统性能影响那么大,到底要怎么査看上下文切换呢?可以使用vmstat这个工具,来查询系统的上下文切换情况

vmstat是常用的系统性能分析工具,主要用来分析系统的内存使用情况,也常用来分析 CPU 上下文切换和中断的次数

1
2
3
4
5
6
7
[root@0x5c0f ~][0]$ vmstat 2
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 4  0      0 10895260  13356 7206976    0    0    34    24  186  109  4  2 94  0  0
 2  0      0 10944452  13356 7179112    0    0     0    14 3414 3917  4  2 94  0  0
 0  0      0 10940036  13356 7179008    0    0     0  1404 2930 3534  4  2 95  0  0
 0  0      0 10953532  13356 7168816    0    0     0   114 2823 3232  3  2 95  0  0
  • procs(进程)
    • r:当前运行队列中线程的数目,代表线程处于可运行状态,但CPU还未能执行,这个值可以作为判断CPU是否繁忙的一个指标;当这个值超过了CPU数目,就会出现CPU瓶颈了;这个我们可以结合top命令的负载值同步评估系统性能(等待运行的进程数((Running or Runnable)是就绪队列的长度,也就是正在运行和等待CPU的进程数))
    • b:处在非中断睡眠状态的进程数
  • system(系统)这2个值越大,会看到由内核消耗的CPU时间会越大
    • in:(interrupt)则是每秒中断的次数,包括时钟中断
    • cs: (context switch)是每秒上下文切换的次数
  • cpu(以百分比表示)
    • us用户进程执行时间(user time);
    • sy系统进程执行时间(system time);
    • id:空闲时间(包括IO等待时间);
    • wa:等待IO时间;wa的值高时,说明IO等待比较严重,这可能由于磁盘大量作随机访问造成,也有可能磁盘出现瓶颈。

  r: 表示运行队列(就是说多少个进程真的分配到CPU),我测试的服务器目前CPU比较空闲,没什么程序在跑,当这个值超过了CPU数目,就会出现CPU瓶颈了。这个也和top的负载有关系,一般负载超过了3就比较高,超过了5就高,超过了10就不正常了,服务器的状态很危险。top的负载类似每秒的运行队列。如果运行队列过大,表示你的CPU很繁忙,一般会造成CPU使用率很高。

  cs:每秒上下文切换次数,例如我们调用系统函数,就要进行上下文切换,线程的切换,也要进程上下文切换,这个值要越小越好,太大了,要考虑调低线程或者进程的数目,例如在apache和nginx这种web服务器中, 我们一般做性能测试时会进行几千并发甚至几万并发的测试,选择web服务器的进程可以由进程或者线程的峰值一直下调,压测,直到cs到一个比较小的值,这个进程和线程数就是比较合适的值了. 系统调用也是,每次调用系统函数,我们的代码就会进入内核空间,导致上下文切换,这个是很耗资源,也要尽量避免频繁调用系统函数。上下文切换次数过多表示你的CPU大部分浪费在上下文切换,导致CPU干正经事的时间少了,CPU没有充分利用,是不可取的。

  vmstat只给出了系统总体的上下文切换情况,要想查看每个进程的详细情况,就需要使用pidstat 了。给它加上-w选项,你就可以查看每个进程上下文切换的情况了。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[root@0x5c0f ~][130]$ pidstat -w 5
Linux 5.14.18-100.fc33.x86_64 (0x5c0f)  2022年09月01日  _x86_64_        (8 CPU)

15时54分47秒   UID       PID   cswch/s nvcswch/s  Command
15时54分52秒     0         2      0.20      0.00  kthreadd
15时54分52秒     0        13      0.60      0.00  ksoftirqd/0
15时54分52秒     0        14     91.42      0.00  rcu_sched
15时54分52秒     0        15      0.20      0.00  migration/0
15时54分52秒     0        18      0.20      0.00  migration/1
15时54分52秒     0        19      0.60      0.00  ksoftirqd/1

  这个结果中有两列内容是我们的重点关注对象。

  一个是cswch,表示每秒自愿上下文切换 (voluntary context switches)的次数,另一个则是nvcswch ,表示每秒非自愿上下文切换 (non voluntary context switches)的次数

  • 所谓自愿上下文切换,是指进程无法获取所需资源,导致的上下文切换。比如说,I/O、内存等系统资源不足时,就会发生自愿上下文切换。

  • 非自愿上下文切换,则是指进程由于时间片巳到等原因,被系统强制调度,进而发生的上下文切换。比如说,大量进程都在争抢CPU时,就容易发生非自愿上下文切换。

  • 这两列如果数值比较大意味着不同的性能问题:

    • 自愿上下文切换时说明进程在等待资源,有可能发生了I/O等问题
    • 非自愿上下文切换,说明进程在被强制调度,也就是在争抢CPU
    • 中断次数多了,说明CPU在被中断处理程序占用。可以通过/proc/interrupts 查看
0%