计算机原理探险系列(一)CPU(下)

简介: 计算机原理探险系列(一)CPU(下)

CPU上下文的切换



在理解了系统内核的调用之后,我们再来理解多个进程之间的切换:

多个进程之间的切换


通常进程的切换是需要由内核态进行控制的,所以一般进程切换过程中难免会需要进行系统的内核调用(也就是上边我所讲到的点)。


在内核态中,会有统一的机制进行这些进程的调度管理,这里面需要:

对cpu的寄存器值进行更新。


保存和更新一些进程的虚拟内存信息,栈信息等。


网络异常,图片无法展示
|


线程之间的切换


同一个进程之间的线程切换


同一个进程里虚拟内存是共享的,所以只需要更新寄存器相关的地址,在进行上下文切换的时候开销会较小一些,但是依旧难免需要进行系统的调用。


不同进程之间的线程切换

由于虚拟内存不同,所以在进行上下文切换的时候和多进程之间切换差不多。


中断上下文的切换

中断上下文切换的时候,主要发生在用户内核态,中断处理会打断进程的正常的调度和执行,被打断的进程或者线程需要暂时记录下它的上下文信息。过多的上下文切换,会把 CPU 时间消耗在寄存器、内核栈以及虚拟内存等数据的保存和恢复上,从而缩短进程真正运行的时间,导致系统的整体性能大幅下降。


进程上下文切换跟系统调用又有什么区别?

首先,进程是由内核来管理和调度的,进程的切换只能发生在内核态。所以,进程的上下文不仅包括了虚拟内存、栈、全局变量等用户空间的资源,还包括了内核堆栈、寄存器等内核空间的状态。


因此,进程的上下文切换就比系统调用时多了一步:在保存当前进程的内核状态和 CPU 寄存器之前,需要先把该进程的虚拟内存、栈等保存下来;而加载了下一进程的内核态后,还需要刷新进程的虚拟内存和用户栈。


如何分析操作系统中的cpu上下文切换情况?


vmstat指令:每隔三秒查看一次操作系统整体的上下文切换情况


vmstat 3

案例:


网络异常,图片无法展示
|


测试机器查看情况


cs(context switch)是每秒上下文切换的次数。
in(interrupt)则是每秒中断的次数。
r(Running or Runnable)是就绪队列的长度,也就是正在运行和等待 CPU 的进程数。
b(Blocked)则是处于不可中断睡眠状态的进程数。
复制代码


pidstat指令:查看整体的切换次数可能在实际问题排查的时候会感觉还不够用,所以这个时候可以结合pidstat指令查看每个线程的上下文切换详情。


pidstat -w
复制代码


网络异常,图片无法展示
|


自愿上下文切换(cswch)


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


非自愿上下文切换(nvcswch)


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


自愿上下文切换变多了,说明进程都在等待资源,有可能发生了 I/O 等其他问题。

非自愿上下文切换变多了,说明进程都在被强制调度,也就是都在争抢 CPU,说明 CPU 的确成了瓶颈。


如何理解进程,线程,纤程



进程

分配资源的单位 (分配虚拟内存空间)


线程

执行程序的调度单位(不会分配任何内存空间,共享进程的内存空间)


纤程(fiber)

JVM 运行在用户空间,当它 new 一个 Thread 时,会对应在 OS 中起一个线程(内核空间,通常消耗内存大小为1m左右),所以这叫重量级线程。而纤程则是在用户态自己起一个逻辑空间,在语言层面进行调度, 和线程比起来,协程的切换不需要操作系统进行保存和恢复CPU 上下文,自己的缓存数据等,因为所有的协程都存在于同一个线程之中,所以协程的切换开销很小。一个线程包含多个纤程,又叫协程,只是协程是一个概念,而纤程是 Windows 系统对协程的一个具体实现。


Fiber在语言层面中通过用户态自己维护的栈空间来管理程序计数器,寄存信息保存等操作,不需要和os内核态打交道,这一点比线程要高效许多。


所谓市面上常说的绿色线程更多的是一个逻辑层面的概念,依赖于虚拟机来实现。操作系统对于虚拟机内部如何进行线程的切换并不清楚,从虚拟机外部来看,或者说站在操作系统的角度看,这些都是不可见的。


了解了纤程之后,我们再来看看go语言内部的设计。goroutine是Go并行设计的核心。goroutine说到底其实就是协程,但是它比线程更小,几十个goroutine可能体现在底层就是五六个线程,Go语言内部帮你实现了这些goroutine之间的内存共享。


目前也有一些人私底下开发了些类库以支持Java语言使用fiber,但是不是特别成熟,截止到JDK13,Java对fiber的支持不是很友好,据说JDK14会较好的支持,蛮期待的。

目录
相关文章
|
存储 缓存 Java
「计算机原理」| CPU 缓存 & 缓存一致性 & 伪共享
「计算机原理」| CPU 缓存 & 缓存一致性 & 伪共享
453 0
「计算机原理」| CPU 缓存 & 缓存一致性 & 伪共享
|
算法 调度 数据中心
计算机原理探险系列(九)CPU调度机制
计算机原理探险系列(九)CPU调度机制
183 0
|
存储 缓存 安全
计算机原理探险系列(一)CPU(上)
计算机原理探险系列(一)CPU(上)
188 0
|
缓存 Android开发 芯片
ART世界探险(3) - ARM 64位CPU的架构快餐教程
我们从去年开始走入了ARM的64位时代,本文尝试用最少的知识量,让大家对ARM64-v8a有一个印象,希望篇幅控制在能够让大家在上个厕所或等个公交之类的时间看完
5955 0
|
1月前
|
Linux
Linux rsyslog占用内存CPU过高解决办法
该文档描述了`rsyslog`占用内存过高的问题及其解决方案。
95 4
|
1月前
|
移动开发 运维 监控
掌握Linux运维利器:查看CPU和内存占用,轻松解决性能问题!
掌握Linux运维利器:查看CPU和内存占用,轻松解决性能问题!
135 0
|
1月前
|
移动开发 Linux
Linux下如何查看哪些进程占用的CPU内存资源最多
Linux下如何查看哪些进程占用的CPU内存资源最多
|
1月前
|
机器学习/深度学习 缓存 监控
linux查看CPU、内存、网络、磁盘IO命令
`Linux`系统中,使用`top`命令查看CPU状态,要查看CPU详细信息,可利用`cat /proc/cpuinfo`相关命令。`free`命令用于查看内存使用情况。网络相关命令包括`ifconfig`(查看网卡状态)、`ifdown/ifup`(禁用/启用网卡)、`netstat`(列出网络连接,如`-tuln`组合)以及`nslookup`、`ping`、`telnet`、`traceroute`等。磁盘IO方面,`iostat`(如`-k -p ALL`)显示磁盘IO统计,`iotop`(如`-o -d 1`)则用于查看磁盘IO瓶颈。
148 10
|
1月前
|
存储 弹性计算 固态存储
阿里云服务器CPU内存配置详细指南,如何选择合适云服务器配置?
阿里云服务器配置选择涉及CPU、内存、公网带宽和磁盘。个人开发者或中小企业推荐使用轻量应用服务器或ECS经济型e实例,如2核2G3M配置,适合低流量网站。企业用户则应选择企业级独享型ECS,如通用算力型u1、计算型c7或通用型g7,至少2核4G配置,公网带宽建议5M,系统盘可选SSD或ESSD云盘。选择时考虑实际应用需求和性能稳定性。
569 6
|
9天前
汇编语言(第四版) 实验一 查看CPU和内存,用机器指令和汇编指令编程
汇编语言(第四版) 实验一 查看CPU和内存,用机器指令和汇编指令编程