CPU上下文切换原理剖析

news2024/9/24 7:26:17

CPU上下文

CPU上下文其实是一些环境正是有这些环境的支撑,任务得以运行,而这些环境的硬件条件便是CPU寄存器和程序计数器。CPU寄存器是CPU内置的容量非常小但是速度极快的存储设备,程序计数器则是CPU在运行任何任务时必要的,里面记录了当前运行任务的行数等信息,这就是CPU上下文。

CPU上下文切换

根据任务的不同,CPU的上下文切换就可以分为进程上下文切换、线程上下文切换、中断上下文切换。

在Linux中,Linux按照特权等级,将进程的运行空间分为内核空间和用户空间:

  • 内核空间具有最高权限,可以直接访问所有资源
  • 用户空间只能访问受限资源,不能直接访问内存等硬件设备,要想访问这些特权资源,必须通过系统调用

对于一个进程来说,一般是运行在用户态的,但是当需要访问内存、磁盘等硬件设备的时候需要陷入到内核态中,也就是要从用户态到内核态的转变,而这种转变需要通过系统调用来实现,例如一个打开文件的操作,需要调用open()打开文件,read()读取文件内容,write()将文件内容输出到控制台,最后close()关闭文件,这就是系统调用

在系统调用的过程中同样发发生了CPU上下文切换:

  • CPU寄存器里面原来用户态的指令位置,需要先保存起来,接着运行内核态代码
  • CPU寄存器需要更新为内核态指令的位置,执行内核态代码

系统调用结束后,CPU寄存器需要恢复原来保存的用户态,然后切换为用户空间,所以一次系统调用的过程,会发生两次的CPU上下文切换但是我们一般说系统调用是特权模式切换而不是上下文切换,因为这里没有涉及到虚拟内存等这些进程用户态的资源,也不会切换进程是属于进程之内的上下文切换,进程是由内核来管理和调度的,进程的切换只能发生在内核态,所以进程的上下文包含了虚拟内存、栈、全局变量等用户空间的资源,还包含了内核堆栈、寄存器等内核空间的状态,所以进程的上下文切换要比系统调用更多一步,保存该进程的虚拟内存、栈等用户空间的资源,进程上下文切换一般需要几十纳秒到数微秒的CPU时间,当进程上下文切换次数比较多的情况下爱,将导致CPU将大量的时间耗费在寄存器、内核栈即虚拟内存等资源的保存和恢复上,另外,Linux通过TLB快表来管理虚拟内存到物理内存的映射关系,当虚拟内存更新之后,需要刷新缓存,在这多处理系统上是很复杂的,因为多个处理器共享一个缓存。

下面再来说说什么时候会进行进程的上下文切换,其实就是进程在被调度的时候需要切换上下文,可能是主动地,也有可能是被动的

  • 系统进程正常调度算法导致进程上下文切换,例如目前使用的时间片轮转算法,当一个进程的时间片耗尽之后,CPU会进项进程的调度切换到其他进程
  • 进程在资源不足的时候,会被挂起例如在等待IO或者内存不足的时候,会主动挂起,并且等待系统调度其他进程
  • 当进程通过一些睡眠函数sleep()主动挂起的时候,也会重新调度
  • 当有高优先级的进程运行时,当前进程也会被挂起
  • 当发生硬件中断时,CPU上的进程会被中断挂起

线程上下文切换

线程是调度的基本单位,而进程则是资源拥有的基本单位,也就是说对于内核中的任务调度是以线程为单位,但是进程只是给线程提供了虚拟内存、全局变量等资源,进程与线程之间的区别这里不再介绍
那么线程上下文的切换,其实分为两种情况:

  • 前后两个线程属于不同进程,因为资源不共享,所以这时候的线程上下文切换和进程上下文切换是一致的
  • 前后两个线程属于同一个进程,因为虚拟内存是共享的,所以在切换的时候,虚拟内存这些资源保持不动,只有切换线程的私有数据、寄存器等不共享的资源

所以同进程内的线程切换要比多进程内的线程切换消耗更少的资源


中断上下文切换

中断是为了快速响应硬件的事件,简单来说就是计算机停下当前的事情,去处理其他的事情,然后在回来继续执行之前的任务,例如我们在调用print函数的时候,其实汇编的底层会帮我们调用一条 int 0x80的指令,便是调用0x80号中断
当然,中断要先将当前进程的状态保存下来,这样中断结束后进程仍然可以从原来的状态恢复运行,中断上下文的切换并不涉及进程的用户态,所以当中断程序打断了正在处于用户态的进程,不需要保存和恢复这个进程的虚拟内存、全局变量等用户态资源,只需要保存和恢复这个进程的内核态中的资源包括CPU寄存器、内核堆栈等
对于同一个CPU来说,中断处理比进程拥有更高的优先级,所以中断上下文切换并不会与进程上下文切换同时发生,一般来说中断程序都执行比较快短小精悍,以便快速结束执行之前的任务。当中断上下文切换次数比较多的时候,会耗费大量的CPU
怎么查看系统上下文
上面已经介绍到CPU上下文切换分为进程上下文切换、线程上下文切换、中断上下文切换,那么过多的上下文切换会把CPU的时间消耗在寄存器、内核栈以及虚拟内存等数据的保存和恢复上,缩短进程真正运行的时间,成为系统性能大幅下降的一个因素
所以我们可以使用vmstat这个工具来查询系统的上下文切换情况,vmstat是一个常用的系统性能分析工具,可以用来分析CPU上下文切换和中断的次数。

需要特别关注的是:

  • cswch(voluntary context switches):表示每秒自愿上下文切换的次数
  • nvcswch(non voluntary context switches):表示每秒非自愿上下文切换的次数

这两个概念的分别含义:

  • 自愿上下文切换:进程无法获取所需的资源,导致的上下文切换,例如IO、内存等资源不足时,就会发生自愿上下文切换
  • 非自愿上下文切换:进程由于时间片已到等时间,被系统强制调度,进而发生的上下文切换,例如大量的进程都在争抢CPU时,就容易发生非自愿上下文切换


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/696835.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

亿级数据过滤算法----布隆过滤器

在程序的世界中,布隆过滤器是程序员的一把利器,利用它可以快速地解决项目中一些比较棘手的问题。如网页 URL 去重、垃圾邮件识别、大集合中重复元素的判断和缓存穿透等问题。 布隆过滤器(Bloom Filter)是 1970 年由布隆提出的。它…

水站桶装水订水小程序

水站桶装水订水小程序正式上线,支持多种商品展示形式,会员卡、积分、分销等功能,有需要的老板可以先看演示!​​​​​​​​​​​​​​​​​​​​​

Java框架之spring 的 messaging

写在前面 本文看下spring message相关的内容。 1:Message?Messaging? Message是消息的意思,是一个名词。而Messaging是一个动名词,是将消息发送出去的意思,因此,我们的消息系统是messaging s…

SuperMap iServer 扩展账户信息合规度校验规则

作者:lisong 目录 功能简介配置文件详情扩展和配置流程 功能简介 SuperMap iServer 11i(2023) 新增了扩展账户信息合规度校验规则的能力,您可以灵活定制满足自身项目需求的用户名、密码合规度校验规则,用于校验您创建…

企业邮箱如何修改管理员密码

1、登录企业邮局,点击顶部“邮局管理”。在邮局管理中点击“组织与成员”,在用户列表中,点击“邮局管理员”(postmaster)。 2、在编辑用户中,点击“重置密码”,然后输入新的密码,保存即可。

java中的xxl-job-core完成定时任务的步骤

首先这个是基于docker的所以需要进行docker配置 1、先导入官方提供的SQL到虚拟机中mysql中 2、创建容器 docker run -e PARAMS"--spring.datasource.urljdbc:mysql://192.168.211.136:3306/xxl_job?useUnicodetrue&characterEncodingUTF-8&autoReconnecttrue&a…

2014年全国硕士研究生入学统一考试管理类专业学位联考数学试题——纯题目版

2014 年考研管理类联考数学真题 一、问题求解(本大题共 15 小题,每小题 3 分,共 45 分)下列每题给出 5 个选项中,只有一个是符合要求的,请在答题卡上将所选择的字母涂黑。 1.某部门在一次联欢活动中共设了 …

python接口自动化测试 - configparser配置文件解析器详细使用

configparser简介 ConfigParser模块已在Python 3中重命名为configparser该模块定义了ConfigParser类。 ConfigParser类实现一种基本的配置文件解析器语言,该语言提供的结构类似于 .ini 文件中的结构 Python自动化测试:手把手教你做60个实战项目&#xf…

设计模式(二十三)——解释器模式(Interpreter )

解释器模式(Interpreter ) 实现了一个表达式接口,该接口解释一个特定的上下文 应用 编译器,正则表达式,SQL解析 实现 实现一个一位数的加法运算 public class Interpreter {public int add(String s){if (s.char…

代码复现:基于精英动态反向学习的增强型正余弦算法—EDOLSCA,可用于对比试验

代码复现:基于精英动态反向学习的增强型正余弦算法—EDOLSCA,可用于对比试验。 参考文献:Zhang L, Hu T, Yang Z, et al. Elite and dynamic opposite learning enhanced sine cosine algorithm for application to plat-fin heat exchanger…

带你用Python制作超级经典的2048游戏(文末赠书)

名字:阿玥的小东东 学习:Python、C/C 主页链接:阿玥的小东东的博客_CSDN博客-python&&c高级知识,过年必备,C/C知识讲解领域博主 目录 2048游戏Python实现 本期赠书 2048游戏Python实现 2048游戏是一款非常流行的益智游戏&#xff0…

vue-cli的Nuxt重构

我的博客用vuecli写的,SEO不忍直视。于是用Nuxt重构了代码,过程中踩了无数坑 一:body样式不生效 正常的body样式设置不能生效,需要在nuxt.config.js中配置 1、设置bodyAttrs的class属性,该属性值对应一个类名 2、该…

Unity 聚焦任意大小的物体

聚焦任意大小的物体 🍱效果🥪食用方法 🍱效果 🥪食用方法 💡.安装Cinemachine 💡.把Assets/ZYF/Tools/Camera/Scene/FocusGo/FocusCtrl.prefab拖入场景 💡.调用FocusCtrl.Focus(gameObject)即可…

《kafka 核心技术与实战》课程学习笔记(九)

客户端都有哪些不常见但是很高级的功能? 什么是 Kafka 拦截器? 拦截器基本思想就是允许应用程序在不修改逻辑的情况下,动态地实现一组可插拔的事件处理逻辑链。它能够在主业务操作的前后多个时间点上插入对应的“拦截”逻辑。Spring MVC 拦…

接口跨域问题

只要协议不同/端口号不同/域名不同都会导致跨域问题

深入浅出设计模式 - 中介者模式

博主介绍: ✌博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家✌ Java知识图谱点击链接:体系化学习Java(Java面试专题) 💕💕 感兴趣的同学可以收…

C++之lambda表达式回调函数作为参数(一百四十)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…

【python】matplotlib 绘制火山图、条形图

文章目录 火山图条形图 火山图 绘制火山图,输入是两个datafreme,行是样本名,列是基因名。使用T-test检验绘制基因表达情况。 def minmax_scale(data):import numpy as np# # 示例数据# data np.array([2, 4, 6, 8, 10])# 进行Min-Max标准化…

go并发编程之channel

目录 1.简介 2.channel类型 无缓冲区的channel 无缓冲区channel的创建 带缓冲区的channel 带缓冲区channel的创建 3.channel使用代码演示 4.获取channel中的值 ​编辑 5.单向channel 单向发送data,发送到channel中 单向接收,channel接收数据 6…

汇编的各种指令及使用方法

***************************************************************** 汇编中的符号 1.指令: 能够编译生成一条32位的机器码,且能被CPU识别和执行 2.伪指令:本身不是指令,编译器可以将其替换成若干条等效指令 3.伪操作&#xff1a…