Linux性能优化实战(极客时间)

cpu-上下文切换

2019-10-16  本文已影响0人  Starlightskm

cpu-上下文切换

前奏

在每个进程任务运行之前,CPU需要知道任务从哪加载,又从哪里开始运行,也就是说,系统要实现帮进程任务设置好CPU寄存器和程序计数器

所以,CPU寄存器和程序计数器,是CPU在运行任何任务之前必须依赖的环境,因此也被称作CPU上下文

CPU上下文切换也就是把前一个任务的CPU上下文保存起来,然后加载新任务的向下文到这些寄存器和程序计数器

image.png

CPU上下文切换场景分类

根据任务的不同,CPU上下文切换分为如下的几类:

进程上下文切换

Linux按照特权等级,把进程分为内核空间用户空间

内核空间:

- Ring0:具有最高权限,可以直接访问所有资源

用户空间

- Ring3: 只能访问受限的资源,不能直接访问内存等硬件设备,必须用过系统调用陷入内核,才能访问这些特权资源
image.png

用户态到内核态的转变需要系统调用来完成,

系统调用结束后,CPU 寄存器需要恢复原来保存的用户态,然后在切换到用户空间,继续运行进程。一次系统调用的过程其实发生了两次上下文切换。

进程上下文切换和 系统调用的上下文切换

进程上下文切换: 是从一个进程切换到另一个进程运行

系统调用的上下文切换: 一直是同一个进程在运行,系统调用过程通常称为特权模式切换,而不是上下文切换

区别如下:

- 进程由内核来管理和调度的,进程的切换只能发生在内核态

- 进程上下文切换比系统调用多了一个过程

Linux通过TLB来管理虚拟内存到物理内存的映射关系,当虚拟内存更新之后TLB也需要刷新,内存的访问也会随之变慢。

进程切换时才需要上下文切换,Linux为每个CPU都维护了一个就绪队列,将活跃进程按照优先级和等待CPU的时间进行排序,然后选择最需要CPU的进程,也就是最高优先级和等菜CPU时间最长的进程来运行

进程在什么时候会调度到CPU上运行

-当优先级更高的进程运行时,为了保证高优先级的进程运行,当前的进程会被挂起,由高优先级的进程来运行

线程上下文切换

线程是调度的基本单位,晋城市资源拥有的基本单位。

所谓的内核中的任务调度,实际上调度对象是线程,而进程只是给线程提供了虚拟内存,全局变量等资源。

线程上下文切换的情况:

- 前后两个线程属于不同的进程

- 前后两个线程属于同一个进程,切换的数据只有线程的不共享的数据

- 多线程对于多进程会消耗更少的资源,所以多线程是替代多进程的一个优势

中断上下文切换

为了快速响应硬件时间,中断会打断进程的正常调度和执行,转而调度中断程序,响应设备事件,而中断执行过程中会挂起当前正常的进程。

小结

实战上下文切换

查看整体的CPU上下文切换


[root@www ~]# vmstat 5

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----

 r b swpd free buff cache si so bi bo in cs us sy id wa st

 3 0 0 80144 140508 1143972 0 0 16 25 1 1 1 0 99 0 0

其中:

查看每个进程的CPU详细上下文切换


[root@www ~]# pidstat -w 5

Linux 3.10.0-862.el7.x86_64 (www.cropy.cn) 10/16/19 _x86_64_ (1 CPU)

16:11:34 UID PID cswch/s nvcswch/s Command

16:11:39 0 1 0.80 0.00 systemd

16:11:39 0 3 1.40 0.00 ksoftirqd/0

16:11:39 0 9 28.74 0.00 rcu_sched

16:11:39 0 11 0.40 0.00 watchdog/0

16:11:39 0 29 0.20 0.00 khugepaged

需要记住的参数如下:

案例分析

环境需求

实战测试


[root@www ~]# sysbench --threads=10 --max-time=300 threads run      #开启10个进程的五分钟的基准测试,模拟多线程切换


[root@www ~]# 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

10 0 0 180128 122484 1054324 0 0 12 0 1112 1249403 17 83 0 0 0

 7 0 0 180128 122484 1054336 0 0 4 0 1097 1262657 16 84 0 0 0

 8 0 0 180128 122484 1054340 0 0 0 0 1089 1224114 18 82 0 0 0

 8 0 0 180112 122484 1054340 0 0 0 0 1116 1255382 19 81 0 0 0

 8 0 0 180096 122488 1054340 0 0 36 16 1149 1249025 18 82 0 0 0

发现如下的问题

综合上面的三个点,可以发现CPU的使用率很高


[root@www ~]# pidstat -w -u 1
Linux 3.10.0-862.el7.x86_64 (www.cropy.cn) 10/16/19 _x86_64_ (1 CPU)

16:42:08 UID PID %usr %system %guest %wait %CPU CPU Command

16:42:09 0 22937 0.00 1.00 0.00 0.00 1.00 0 barad_agent

16:42:09 0 31092 17.00 83.00 0.00 0.00 100.00 0 sysbench

16:42:08 UID PID cswch/s nvcswch/s Command

16:42:09 0 1 1.00 0.00 systemd

16:42:09 0 3 1.00 0.00 ksoftirqd/0

16:42:09 0 9 32.00 0.00 rcu_sched

16:42:09 0 9921 1.00 0.00 supervisord

16:42:09 0 10617 1.00 0.00 YDLive

16:42:09 0 16286 2.00 0.00 IntelliJIDEALic

16:42:09 1000 17350 2.00 0.00 sshd

16:42:09 0 22936 3.00 0.00 barad_agent

16:42:09 0 28412 1.00 0.00 kworker/0:1

16:42:09 1003 28963 3.00 0.00 tmux

16:42:09 0 30007 11.00 0.00 kworker/0:0

16:42:09 0 30560 1.00 0.00 vmstat

16:42:09 0 31225 6.00 0.00 ntpdate

16:42:09 0 31226 2.00 0.00 grep

16:42:09 0 31241 1.00 0.00 pidstat

可以发现CPU使用过高是sysbench导致的,pidstat -wt 可以分析到线程级别

也可以如下的方式去查看:


**[root@www ~]# watch -d cat /proc/interrupts **

上一篇 下一篇

猜你喜欢

热点阅读