龙空技术网

分析CPU上下文切换导致的性能问题

韭菜老陈 1480

前言:

目前同学们对“进程切换时会发生什么”大致比较看重,朋友们都想要知道一些“进程切换时会发生什么”的相关文章。那么小编在网摘上搜集了一些关于“进程切换时会发生什么””的相关内容,希望朋友们能喜欢,姐妹们快快来学习一下吧!

一、CPU上下文切换

Linux 是一个多任务的操作系统,它支持远大于CPU数量的任务同时运行,当然并不是真正的同时运行,是每个任务轮流执行CPU分给他们的时间片,让人感觉是同时在运行。每一个任务运行前,CPU都需要知道任务从哪里加载,又从哪里运行,也就是说,需要系统事先设置好CPU寄存器。CPU寄存器包含指令寄存器(IR)和程序计数器(PC)。他们用来暂存指令,数据和地址,程序运行的下一条指令地址,这些都是任务运行时的必要环境。因此也被称作CPU上下文

上下文切换就是把前一个任务的CPU上下文保存起来,然后加载新任务的上下文到这些指令寄存器(IR)和程序寄存器(PC)等寄存器中。这些被保存下来的上下文会存储在操作系统的内核中,等待任务重新调度执行时再次加载进来,这样就能保证任务的原来状态不受影响,让任务看起来是连续运行的。

根据场景不同,CPU的上下文切换又分为进程上下文切换,线程上下文切换以及中断上下文切换。

1、进程和线程的区别:

进程是资源分配和执行的基本单位;线程是任务调度和运行的基本单位。线程没有资源,进程给指针提供虚拟内存、栈、变量等共享资源,而线程可以共享进程的资源。

进程上下文切换:是指从一个进程切换到另一个进程。进程运行态为内核运行态和进程运行态。内核空间态资源包括内核的堆栈、寄存器等;用户空间态资源包括虚拟内存、栈、变量、正文、数据等。

系统调用(软中断)在内核态完成的,需要进行2次CPU上下文切换(用户空间-->内核空间-->用户空间),不涉及用户态资源,也不会切换进程。进程是由内核来管理和调度的,进程的切换只能发生在内核态。所以,进程的上下文不仅包括了用户空间的资源,也包括内核空间资源。

2、进程的上下文切换过程:

(1)接收到切换信号,挂起进程,记录当前进程的虚拟内存、栈等资源存储;

(2)将这个进程在 CPU 中的上下文状态存储于起来;

(3)然后在内存中检索下一个进程的上下文;

(4)并将其加载到 CPU的寄存器中恢复;

(5)还需要刷新进程的虚拟内存和用户栈;

(6)最后跳转到程序计数器所指向的位置,以恢复该进程。

以下情况将会触发进程上下文切换:

1、根据调度策略,将CPU时间划片为对应的时间片,当时间片耗尽,当前进程必须挂起。

2、资源不足的,在获取到足够资源之前进程挂起。

3、进程sleep挂起。

4、高优先级进程导致当前进度挂起

5、硬件中断,导致当前进程挂起

3、线程上下文切换:

1、不同进程之间的线程上下文切换,其过程和进程上下文切换大致相同。

2、进程内部的线程进上下文切换。不需要切换进程的用户资源,只需要切换线程私有的数据和寄存器等。这会比进程上下文进程切换消耗的资源少,所以多线程相比多进程的优势。

4、中断上下文切换:

快速响应硬件的事件,中断处理会打断进程的正常调度和执行。同一CPU内,硬件中断优先级高于进程。切换过程类似于系统调用的时候,不涉及到用户运行态资源。但大量的中断上下文切换同样可能引发性能问题。

二、查看上下文切换情况

既然过多的上下文切换会把CPU的时间消耗在上下文环境的保存上,并没有充分利用其计算功能。那就需要查看当前系统的上下文切换情况了。

1、vmstat 查看系统的上下文切换情况

vmstat

可观察到 cs 瞬间上升(第一行是开机以来的参数的平均值),其中各个字段的含义:

cs (centext switch) 每秒的上下文切换次数

in (interrupt) 每秒的中断次数

r (Runing or Runnable) 就绪队列的长度,也就是正在运行和等待CPU的进程数。

b (Blocked) 不可中断睡眠状态的进程数

这里的数据是使用的sysbench,模拟操作系统的多线程调度瓶颈,以10个线程运行5分钟的基准测试,模拟多线程切换。

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

2、pidstat 可以看到具体的某个应用程序的上下文切换情况

这里需要加上 -t 参数,显示线程,不带参数,看不到sysbench,加上-t后可以看到 sysbench 发生了大量的自愿上下文切换。

pidstat

其中:

cswch (voluntary context switches) 自愿上下文切换,指的是进程无法获得所需的资源导致的上下文切换,比如I/O不足,内存不足。

nvcswch (non voluntary context switches) 非自愿上下文切换,指的是 进程由于时间片已到等原因,被系统强制调度,进而发生上下文切换,比如大量进程在争抢CPU。

一般上下文切换在数百到一万之内上下文切换超过1万,很可能遇到性能问题。需要具体看看了。

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

参考链接:

标签: #进程切换时会发生什么