cpu上下文切换(下)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cpu上下文切换(下)相关的知识,希望对你有一定的参考价值。

cpu上下文切换如何查看

上一篇介绍了cpu上下文切换几种场景以及数据保存恢复过程,这篇文章介绍如何查看cpu上下文切换

一、vmstat

安装:yum install -y sysstat

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

# vmstat <br/>procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----<br/>r b swpd free buff cache si so bi bo in cs us sy id wa st<br/>1 0 0 1030608 972 119296 0 0 52 15 0 1 4 0 95 0 0

  • cs(context switch)是每秒上下文切换的次数。

  • in(interrupt)是每秒中断的次数。

  • r(Running or Runnable)是就绪队列的长度,也就是等待和运行cpu的进程数。

  • b(Blocked)是处于不可中断睡眠状态的进程数。

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

二、pidstat

pidstat -w 5

Linux 3.10.0-514.26.2.el7.x86_64 (nodejs-test) 06/09/2019 _x86_64_ (2 CPU)

10:53:49 AM UID PID cswch/s nvcswch/s Command
10:53:54 AM 0 9 21.56 0.00 rcu_sched
10:53:54 AM 0 10 0.40 0.00 watchdog/0
10:53:54 AM 0 11 0.40 0.00 watchdog/1
10:53:54 AM 0 12 0.40 0.00 migration/1
10:53:54 AM 0 13 0.40 0.00 ksoftirqd/1

  • cswch:每秒自愿上下文切换的次数。

  • nvcswch:每秒非自愿上下文切换的次数。

  • 自愿上下文切换,是指进程无法获取所需资源,导致上下文切换,如:I/O、内存等资源不足时。

  • 非自愿上下文切换,是指进程由于时间片已到等原因,被系统强制调度,进而发生上下文切换。如:大量进程争抢cpu。

    案例

    操作

    打开三个终端

    1. 创造事故

      以 10 个线程运行 5 分钟的基准测试,模拟多线程切换的问题

      $ sysbench --threads=10 --max-time=300 threads run

    2. 打开第二个中断查看

      每隔 1 秒输出 1 组数据(需要 Ctrl+C 才结束)

      $ vmstat 1
      procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
      r b swpd free buff cache si so bi bo in cs us sy id wa st
      6 0 0 6487428 118240 1292772 0 0 0 0 9019 1398830 16 84 0 0 0
      8 0 0 6487428 118240 1292772 0 0 0 0 10191 1392312 16 84 0 0 0

    • cs列的上下文切换次数升到了139万。
    • r列:就绪队列到达了8。超过了cpu的个数。此时肯定有大量cpu竞争。
    • us和sy列加起来100%。sy列高达84%,说明cpu主要是被内核占用了。
    • in列:中断次数上升到1万左右,说明中断处理也是问题。
    1. pidstat

      利用pidstat查看进程上下文切换详细情况;

      #每隔 1 秒输出 1 组数据(需要 Ctrl+C 才结束)

      -w 参数表示输出进程切换指标,而 -u 参数则表示输出 CPU 使用指标

      $ pidstat -w -u 1
      08:06:33 UID PID %usr %system %guest %wait %CPU CPU Command
      08:06:34 0 10488 30.00 100.00 0.00 0.00 100.00 0 sysbench
      08:06:34 0 26326 0.00 1.00 0.00 0.00 1.00 0 kworker/u4:2

      08:06:33 UID PID cswch/s nvcswch/s Command
      08:06:34 0 8 11.00 0.00 rcu_sched
      08:06:34 0 16 1.00 0.00 ksoftirqd/1
      08:06:34 0 471 1.00 0.00 hv_balloon
      08:06:34 0 1230 1.00 0.00 iscsid
      08:06:34 0 4089 1.00 0.00 kworker/1:5
      08:06:34 0 4333 1.00 0.00 kworker/0:3
      08:06:34 0 10499 1.00 224.00 pidstat
      08:06:34 0 26326 236.00 0.00 kworker/u4:2
      08:06:34 1000 26784 223.00 0.00 sshd

    ? 从上面输出看出,sysbench进程占用cpu100%,自愿上下文切换频率高的内核线程为sshd和 kwordker。但是,加起来也就是几百,没有达到139万。

    1. pidstat -t参数

      #每隔 1 秒输出一组数据(需要 Ctrl+C 才结束)

      #-wt 参数表示输出线程的上下文切换指标

      $ pidstat -wt 1
      08:14:05 UID TGID TID cswch/s nvcswch/s Command
      ...
      08:14:05 0 10551 - 6.00 0.00 sysbench
      08:14:05 0 - 10551 6.00 0.00 |__sysbench<br/>08:14:05 0 - 10552 18911.00 103740.00 |__sysbench
      08:14:05 0 - 10553 18915.00 100955.00 |__sysbench<br/>08:14:05 0 - 10554 18827.00 103954.00 |__sysbench
      ...

      此时看出,sysbench主进程上下文切换次数不多,但是子线程却很多。

      前面我们看见,不止上下文切换频率升高,还有中断次数。

      一旦CPU接收了中断请求,CPU就会暂时停止执行正在运行的程序,并且调用一个称为中断处理器或中断服务程序(interrupt service routine)的特定程序。

      查看文件接口

      #cat /proc/interrupts

      ? CPU0 CPU1
      25: 10652623 80703151 PCI-MSI-edge virtio3-req.0
      26: 0 0 PCI-MSI-edge virtio2-config
      27: 2 0 PCI-MSI-edge virtio2-virtqueues
      28: 0 0 PCI-MSI-edge virtio0-config
      29: 599781 28812335 PCI-MSI-edge virtio0-input.0
      30: 2 506 PCI-MSI-edge virtio0-output.0
      31: 0 0 PCI-MSI-edge virtio1-config
      32: 6893540 111078549 PCI-MSI-edge virtio1-input.0
      33: 615 1368 PCI-MSI-edge virtio1-output.0
      NMI: 0 0 Non-maskable interrupts
      LOC: 3818014562 3882568092 Local timer interrupts
      SPU: 0 0 Spurious interrupts
      PMI: 0 0 Performance monitoring interrupts
      IWI: 92938221 96288600 IRQ work interrupts
      RTR: 0 0 APIC ICR read retries
      RES: 316386309 327268304 Rescheduling interrupts
      CAL: 71367577 3699711 Function call interrupts
      TLB: 21377263 20572311 TLB shootdowns
      TRM: 0 0 Thermal event interrupts
      THR: 0 0 Threshold APIC interrupts

      中的RES: 316386309 327268304 Rescheduling interrupts

    总结

    • 自愿上下文切换变多了,说明进程都在等待资源,有可能发生了IO等其他问题
    • 非自愿上下文切换变多了,说明进程在被强制调度,也就是在争抢cpu,说明cpu的确成了瓶颈
    • 中断次数变多了,说明cpu被中断处理程序占用,需要查看/proc/interrupts 接口文件。

以上是关于cpu上下文切换(下)的主要内容,如果未能解决你的问题,请参考以下文章

2.2 CPU 上下文切换是什么意思?(下)

Java代码分析和CPU高的方法分析

CPU上下文切换的次数和时间(context switch)

Linux性能学习(1.3):CPU_CPU上下文切换

Linux性能学习(1.3):CPU_CPU上下文切换

Linux性能学习(1.3):CPU_CPU上下文切换