操作系统-CPU概念部分01-性能指标-平均负载-上下文切换-CPU使用率

参考来源:
极客时间-Linux性能优化实战
参考书籍-《操作系统概念》

linux性能优化-cpu-性能指标整体概览
在这里插入图片描述

性能指标-平均负载

场景案例:
A:X工,新业务接入后,新上架设备运行的怎么样,能抗住业务压力吗?是否需要扩容呀?
B:我是X工,(结论)目前设备运行平稳,(依据)刚登陆设备看了平均负载的指标(执行 top 或者 uptime 命令,查看load average的三个值),目前1分钟,5分钟,15分钟数据平稳,已经根据监控任务,(定时)每N小时记录平均负载信息,(预警)根据预设的平均负载指标进行告警,会有短信和邮件提醒,会持续关注设备运行状态,请放心。

平均负载的概念

平均负载是指单位时间内,系统处于可运行状态和不可中断状态平均进程数
也就是平均活跃进程数,它和 CPU 使用率并没有直接关系。可以理解为平均负载其实就是平均活跃进程数

这里我先解释下,可运行状态和不可中断状态这俩词儿

可运行状态和不可终端状态的进程

可运行状态的进程,是指正在使用 CPU 或者正在等待 CPU 的进程,也就是我们常用
ps 命令看到的,处于 R 状态(Running 或 Runnable)的进程。

不可中断状态的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断的,比
如最常见的是等待硬件设备的 I/O 响应,也就是我们在 ps 命令中看到的 D 状态
(Uninterruptible Sleep,也称为 Disk Sleep)的进程。(类比项目管理中的关键路径,不可被绕过)

比如,当一个进程向磁盘读写数据时,为了保证数据的一致性,在得到磁盘回复前,它是不
能被其他进程或者中断打断的,这个时候的进程就处于不可中断状态。如果此时的进程被打
断了,就容易出现磁盘数据与进程数据不一致的问题。

所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制。

平均负载为多少时合理

平均负载最理想的情况是等于 CPU 个数。所以在评判平均负载时,首先你要知
道系统有几个 CPU,这可以通过 top 命令或者从文件 /proc/cpuinfo 中读取

root@ub1804:/home/xiaoyue# grep "model name" /proc/cpuinfo |wc -l
4

三个不同时间间隔的平均值,其实给我们提供了,分析系统负载趋势的数
据来源,让我们能更全面、更立体地理解目前的负载状况。

通过man uptime,搜索load average关键字查看信息
在这里插入图片描述
(三种趋势:大于,等于,小于)
如果1分钟、5分钟、15分钟的三个值基本相同,或者相差不大,那就说明系统负载很
平稳

但如果1分钟的值远小于15分钟的值,就说明系统最近1分钟的负载在减少,而过去
15分钟内却有很大的负载,
反过来,如果1分钟的值远大于15分钟的值,就说明最近1分钟的负载在增加,这种
增加有可能只是临时性的,也有可能还会持续增加下去,所以就需要持续观察。一旦1
分钟的平均负载接近或超过了CPU的个数,就意味看系统正在发生过载的问题,这时就
得分析调查是哪里导致的问题,并要想办法优化了。

平均负载和CPU使用率的区别

平均负载是指单位时间内,处于可运行状态和不可中
断状态的进程数。所以,它不仅包括了正在使用 CPU 的进程,还包括等待 CPU 和等待
I/O 的进程。

CPU 使用率,是单位时间内 CPU 繁忙情况的统计,跟平均负载并不一定完全对应。比
如:

CPU 密集型进程,使用大量 CPU 会导致平均负载升高,此时这两者是一致的;

I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高;

大量等待 CPU 的进程调度也会导致平均负载升高,此时的 CPU 使用率也会比较高。

可以用 iostat、mpstat、pidstat 等工具,找出平均负载升高的根源。

————————分隔符————————————

性能指标- CPU上下文切换

在每个任务运行前,CPU 都需要知道任务从哪里加载、又从哪里开始运行,也就是说,
需要系统事先帮它设置好 CPU 寄存器和程序计数器(Program Counter,PC)。

CPU 寄存器,是 CPU 内置的容量小、但速度极快的内存。而程序计数器,则是用来存储
CPU 正在执行的指令位置、或者即将执行的下一条指令位置。它们都是 CPU 在运行任何任
务前,必须的依赖环境,因此也被叫做 CPU 上下文

CPU上下文切换(自愿、非自愿)

CPU 上下文切换,就是先把前一个任务的 CPU 上下文(也就是 CPU 寄存器和程序计数器)保存起来,然后加
载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务。

而这些保存下来的上下文,会存储在系统内核中,并在任务重新调度执行时再次加载进来。
这样就能保证任务原来的状态不受影响,让任务看起来还是连续运行。

CPU 上下文切换无非就是更新了 CPU 寄存器的值嘛,但这些寄存器,
本身就是为了快速运行任务而设计的,为什么会影响系统的 CPU 性能呢?

这两个概念你一定要牢牢记住,因为它们意味着不同的性能问题:
所谓自愿上下文切换,是指进程无法获取所需资源,导致的上下文切换。比如说, I/O、
内存等系统资源不足时,就会发生自愿上下文切换。

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

CPU上下文切换的三种场景

根据任务的不同,CPU 的上下文切换就可以分为几个不同的场景,也就是进程上下文切换、线程上下文切换以及中断上下文切换。

根据任务的不同,CPU 的上下文切换就可以分为几个不同的场景,也就是进程上下
文切换、线程上下文切换以及中断上下文切换。

来自书籍-操作系统概念

进程上下文切换

CPU 特权等级的 Ring 0 和 Ring 3

内核空间(Ring 0)具有最高权限,可以直接访问所有资源;
用户空间(Ring 3)只能访问受限资源,不能直接访问内存等硬件设备,必须通过系统
调用陷入到内核中,才能访问这些特权资源

换个角度看,也就是说,进程既可以在用户空间运行,又可以在内核空间中运行。进程在用
户空间运行时,被称为进程的用户态,而陷入内核空间的时候,被称为进程的内核态。

从用户态到内核态的转变,需要通过系统调用来完成。比如,当我们查看文件内容时,就需
要多次系统调用来完成:首先调用 open() 打开文件,然后调用 read() 读取文件内容,并
调用 write() 将内容写到标准输出,最后再调用 close() 关闭文件

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

**进程上下文切换,是指从一个进程切换到另一个进程运行。**而系统调用过程中一直是同一个进程在运行。

所以,系统调用过程通常称为特权模式切换,而不是上下文切换。但实际上,系统调用过程
中,CPU 的上下文切换还是无法避免的。

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

Linux 通过 TLB(Translation Lookaside Buffer)来管理虚拟内存到物
理内存的映射关系。当虚拟内存更新后,TLB 也需要刷新,内存的访问也会随之变慢。特
别是在多处理器系统上,缓存是被多个处理器共享的,刷新缓存不仅会影响当前处理器的进
程,还会影响共享缓存的其他处理器的进程。

触发进程调度的场景梳理

进程在什么时候才会被调度到 CPU 上运行呢?
其一,为了保证所有进程可以得到公平调度,CPU时间被划分为一段段的时间片,这些时
间片再被轮流分配给各个进程。这样,当某入进程的时间片耗尽了,就会被系统挂起,切换
到其它正在等待CPU的进程运行,
其二,进程在系统资源不足(比如内存不足)时,要等到资源满定后才可以运行,这个时候
进程也会被挂起,并由系统调度其他进程运行。
其三,当进程通过睡眠函数sleep这样的方法将自己主动挂起时,自然也会重新调度。
其四,当有优先级更高的进程运行时,为了保证高优先级进程的运行,当前进程会被挂起
由高优先级进程来运行。
最后一个,发生硬件中断时,CPU上的进程会被中断挂起,转而执行内核中的中断服务程
序。
(时间片耗尽、资源不足没法运行、主动挂起、礼让行人、物理超度)

线程的上下文切换

第一种, 前后两个线程属于不同进程。此时,因为资源不共享,所以切换过程就跟进程上
下文切换是一样。

第二种,前后两个线程属于同一个进程。此时,因为虚拟内存是共享的,所以在切换时,虚
拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据。

中断上下文切换

除了前面两种上下文切换,还有一个场景也会切换 CPU 上下文,那就是中断。

为了快速响应硬件的事件,中断处理会打断进程的正常调度和执行,转而调用中断处理程
序,响应设备事件。而在打断其他进程时,就需要将进程当前的状态保存下来,这样在中断
结束后,进程仍然可以从原来的状态恢复运行。

跟进程上下文不同,中断上下文切换并不涉及到进程的用户态。所以,即便中断过程打断了
一个正处在用户态的进程,也不需要保存和恢复这个进程的虚拟内存、全局变量等用户态资
源。中断上下文,其实只包括内核态中断服务程序执行所必需的状态,包括 CPU 寄存器、
内核堆栈、硬件中断参数等。

对同一个 CPU 来说,中断处理比进程拥有更高的优先级,所以中断上下文切换并不会与进
程上下文切换同时发生。同样道理,由于中断会打断正常进程的调度和执行,所以大部分中
断处理程序都短小精悍,以便尽可能快的执行结束。(那个,我提一句啊~)

另外,跟进程上下文切换一样,中断上下文切换也需要消耗 CPU,切换次数过多也会耗费
大量的 CPU,甚至严重降低系统的整体性能。所以,当你发现中断次数过多时,就需要注
意去排查它是否会给你的系统带来严重的性能问题。

到底要怎么查看上下文切换呢?
在这里,我们可以使用 vmstat 这个工具,来查询系统的上下文切换情况。(改天整理)

每秒上下文切换多少次才算正常呢?

这个数值其实取决于系统本身的 CPU 性能。在我看来,如果系统的上下文切换次数比较稳
定,那么从数百到一万以内,都应该算是正常的。但当上下文切换次数超过一万次,或者切
换次数出现数量级的增长时,就很可能已经出现了性能问题。

这时,你还需要根据上下文切换的类型,再做具体分析。比方说:
自愿上下文切换变多了,说明进程都在等待资源,有可能发生了 I/O 等其他问题;

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

中断次数变多了,说明 CPU 被中断处理程序占用,还需要通过查看 /proc/interrupts 文件来分析具体的中断类型

性能指标-CPU 使用率

(定义)CPU 使用率,就是除了空闲时间外的其他时间占总 CPU 时间的百分比。

CPU使用率相关指标

CPU 使用率相关的重要指标,你还会在很多其他的性能工具中看到它们。下面,我来依次解读一下。

user(通常缩写为 us),代表用户态 CPU 时间。注意,它不包括下面的 nice 时间,但
包括了 guest 时间。
nice(通常缩写为 ni),代表低优先级用户态 CPU 时间,也就是进程的 nice 值被调整
为 1-19 之间时的 CPU 时间。这里注意,nice 可取值范围是 -20 到 19,数值越大,优
先级反而越低。
system(通常缩写为 sys),代表内核态 CPU 时间。
idle(通常缩写为 id),代表空闲时间。注意,它不包括等待 I/O 的时间(iowait)。
iowait(通常缩写为 wa),代表等待 I/O 的 CPU 时间。
irq(通常缩写为 hi),代表处理硬中断的 CPU 时间。
softirq(通常缩写为 si),代表处理软中断的 CPU 时间。
steal(通常缩写为 st),代表当系统运行在虚拟机中的时候,被其他虚拟机占用的 CPU
时间。
guest(通常缩写为 guest),代表通过虚拟化运行其他操作系统的时间,也就是运行虚
拟机的 CPU 时间。
guest_nice(通常缩写为 gnice),代表以低优先级运行虚拟机的时间。

Linux 通过 /proc 虚拟文件系统,向用户空间提供了系统内部状态的信息,而 /proc/stat
提供的就是系统的 CPU 和任务统计信息。比方说,如果你只关注 CPU 的话,可以执行下
面的命令:
通过man top,查询TASK and CPU States
在这里插入图片描述

CPU 使用率的计算方法(系统、进程)

在这里插入图片描述
系统 CPU 使用率的计算方法,那进程的呢?跟系统的指标类似,Linux
也给每个进程提供了运行情况的统计信息,也就是 /proc/[pid]/stat。不过,这个文件包含
的数据就比较丰富了,总共有 52 列的数据。

当然不是,各种各样的性能分析工具已经帮我们计算好了。不过要注意的是,性能分析工具
给出的都是间隔一段时间的平均 CPU 使用率,所以要注意间隔时间的设置,特别是用多个
工具对比分析时,你一定要保证它们用的是相同的间隔时间。

比如,对比一下 top 和 ps 这两个工具报告的 CPU 使用率,默认的结果很可能不一样,因
top 默认使用 3 秒时间间隔(在top命令的显示界面中,通常会有一个字段显示当前的时间信息。由于top命令默认每3秒刷新一次,您可以注意这个时间字段的变化来确认刷新间隔。),而 ps 使用的却是进程的整个生命周期。

怎么查看 CPU 使用率

top 显示了系统总体的 CPU 和内存使用情况,以及各个进程的资源使用情况。
ps 则只显示了每个进程的资源使用情况。

CPU 使用率过高怎么办?(不同CPU使用率过高的排查思路)

你可能又想知道,占用 CPU 的到底是代码里的哪个函数呢?找到它,你才能
更高效、更针对性地进行优化。

我猜你第一个想到的,应该是 GDB(The GNU Project Debugger), 这个功能强大的程
序调试利器。的确,GDB 在调试程序错误方面很强大。但是,我又要来“挑刺”了。请你
记住,GDB 并不适合在性能分析的早期应用。

那么哪种工具适合在第一时间分析进程的 CPU 问题呢?我的推荐是 perf。perf 是 Linux
2.6.31 以后内置的性能分析工具。它以性能事件采样为基础,不仅可以分析系统的各种事
件和内核性能,还可以用来分析指定应用程序的性能问题。

CPU 使用率是最直观和最常用的系统性能指标,更是我们在排查性能问题时,通常会关注
的第一个指标。所以我们更要熟悉它的含义,尤其要弄清楚用户(%user)、Nice(%nice)、系统(%system) 、等待 I/O(%iowait) 、中断(%irq)以及软中断
(%softirq)这几种不同 CPU 的使用率。比如说:

用户 CPU 和 Nice CPU 高,说明用户态进程占用了较多的 CPU,所以应该着重排查进
程的性能问题。
**系统 CPU 高,**说明内核态占用了较多的 CPU,所以应该着重排查内核线程或者系统调用
的性能问题。
I/O 等待 CPU 高,说明等待 I/O 的时间比较长,所以应该着重排查系统存储是不是出现
了 I/O 问题。
软中断和硬中断高,说明软中断或硬中断的处理程序占用了较多的 CPU,所以应该着重
排查内核中的中断服务程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值