LINUX性能优化--cpu基础概念

cpu是计算机系统的大脑,这个重要性不可置否。
在性能优化的过程中,指标是很重要的。那么cpu需要关注哪几个方面的指标呢?
有以下几个指标是需要关注的:
1 使用率
2 平均负载
3 上下文切换
分别谈一下上面的几个指标是什么意思?

1 CPU使用率:

定义:除了空闲时间外的其他时间占总 CPU 时间的百分比
那么内核是怎么管理cpu时间的呢?
Linux 通过事先定义的节拍率(内核中表示为 HZ),触发时间中断,并使用全局变量 Jiffies 记录了开机以来的节拍数。每发生一次时间中断,Jiffies 的值就加 1。
命令:grep ‘CONFIG_HZ=’ /boot/config-$(uname -r)
输出:CONFIG_HZ=250
通过上面的命令就可以得出系统设定的节拍率
但这是在系统空间里面的,在用户空间是不能直接访问的,为了方便用户空间访问,有一个是用户空间节拍率,总是固定的100,所以对于用户空间程序总是看到的是1/100秒。
LINUX是怎么向用户空间提供系统状态信息的呢?
当然是/proc虚拟文件系统,如果查看cpu状态信息,可以通过命令:
cat /proc/stat | grep ^cpu
cpu 57739 457 17017 5285697 68727 0 668 0 0 0
cpu0 4262 34 1112 443907 3145 0 334 0 0 0
cpu1 5492 22 1493 441946 3453 0 117 0 0 0
cpu2 4969 34 1324 442719 3621 0 47 0 0 0
cpu3 5123 26 1295 443813 2383 0 15 0 0 0
cpu4 5530 23 1331 442580 3169 0 16 0 0 0
cpu5 4858 17 1251 443236 3133 0 5 0 0 0
cpu6 5741 168 1396 423352 21805 0 41 0 0 0
cpu7 4578 21 1137 439739 6870 0 76 0 0 0
cpu8 2872 23 2896 440043 5680 0 1 0 0 0
cpu9 4736 23 1225 439472 7173 0 10 0 0 0
cpu10 4760 24 1383 442000 4530 0 1 0 0 0

每一列都代表什么意思呢?
通过man proc 然后查找 /proc/stat里面就有详细的介绍,通常在很多的系统工具也能看到他们的身影。
他们分别的意思是:
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),代表以低优先级运行虚拟机的时间。

通过上面的介绍,接下来说一下cpu使用率的计算
公式如下:
在这里插入图片描述d
通过/proc/stat的数据很容易就可以算出cpu的使用率。
但这有个问题?
就是/proc/stat 统计的是开机以来的节拍数累计值,那么这里算出来的就是开机以来的平均cpu使用率。
一般也没什么用。
那么比较有参考价值的数据应该是每隔一段时间,然后取这个间隔时间内的平均cpu使用率,各种性能工具采用的就是这个计算方法。公式如下:
在这里插入图片描述
比如top工具是每隔3秒采集一次数据。
那么通过不同的性能查看数据的时候,就要注意时间间隔的设置了。
pidstat,top都可以查看cpu的数据。
如果发现cpu使用率有异常可以通过gdb,perf工具去检查。

2 平均负载

到底什么是平均负载??
通过查看man uptime 里面有解释:
平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数。
这个可以看出平均负载跟cpu使用率没有半毛钱的关系。
那么问题又来了?什么叫可运行状态,什么叫不可中断状态?
A process in a runnable state is either using the CPU or waiting to use the CPU
可运行状态的进程,是指正在使用 CPU 或者正在等待 CPU 的进程,在ps工具里面看到的R
A process in uninterruptable state is waiting for some I/O access, eg waiting for disk
不可中断状态就是在等待硬件设备的 I/O 响应,是系统的关键流程,不可以被打断的。在ps工具里面看到的D
那么当平均负载为1的时候,如果是在单核状态下,表示系统被完全占用,在4核的情况下,有75%的空闲。
那么多少是合理的呢?
一般来说超过CPU数量的70%的时候就要排查问题了,此时就可能会产生系统响应变慢的问题。如果达到cpu数量就表示cpu已经过载了。
平均负载有三个值,要看哪一个呢?
三个都要看,这三个值是给了我们分析系统负载趋势的来源,可以更全面的了解现在系统的状态。
如果 1 分钟、5 分钟、15 分钟的三个值基本相同,或者相差不大,那就说明系统负载很平稳。但如果 1 分钟的值远小于 15 分钟的值,就说明系统最近 1 分钟的负载在减少,而过去 15 分钟内却有很大的负载。反过来,如果 1 分钟的值远大于 15 分钟的值,就说明最近 1 分钟的负载在增加,这种增加有可能只是临时性的,也有可能还会持续增加下去,所以就需要持续观察。一旦 1 分钟的平均负载接近或超过了 CPU 的个数,就意味着系统正在发生过载的问题,这时就得分析调查是哪里导致的问题,并要想办法优化了
假设我们在一个单 CPU 系统上看到平均负载为 1.73,0.60,7.98,那么说明在过去 1 分钟内,系统有 73% 的超载,而在 15 分钟内,有 698% 的超载,从整体趋势来看,系统的负载在降低。
跟CPU使用率是一个什么关系呢?
CPU 密集型进程,使用大量 CPU 会导致平均负载升高,此时这两者是一致的;
I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高;
大量等待 CPU 的进程调度也会导致平均负载升高,此时的 CPU 使用率也会比较高

3 上下文切换

这就引出来一个问题,到底什么是上下文?

首先来看看linux是怎么运行的,linux是一个多任务的操作系统,但计算机系统的cpu个数是固定的,不可能做成无限多的。比如我的计算机是2核的,那么怎么可以做到我同时敲代码,听歌,看文档等等。
这个就是cpu时间片的概念了,可以运行的任务(进程和线层,简单统一下说任务)都会排在就绪队列里面,cpu会从就绪队列根据cpu调度算法(比如,cfq完全公平调度算法)选择一个任务进行运行,当时间片到的时候,就会保存现场,选择另外一个任务运行。保存的现场包括什么东西呢?因为cpu需要知道从哪里开始执行任务,需要从哪里获得数据。那么就需要提前设置好程序计数器和寄存器。这些是cpu需要依赖的环境,就叫做上下文。
但是本身寄存器就是快速运行任务设计的,然后上下文切换不就是改变了这些寄存器的值,为什么会产生性能消耗呢?
在linux操作系统里面,任务指的是进程,线程和由硬件产生的中断。所有可以分为三种上下文切换。分别是进程上下文切换,线程上下文切换和中断上下文切换。
进程上下文切换
操作系统分为内核态和用户态。进程的切换必须发生在内核态,那么需要保存下来的信息就有:
1 虚拟内存空间,栈,全局变量等用户空间的资源
2 内核堆栈和寄存器等内核空间的资源
执行的过程:
1 该进程的虚拟内存、栈等保存下来
2 保存当前进程的内核状态和 CPU 寄存器
3 加载了下一进程的内核态
4 刷新进程的虚拟内存和用户栈
如下图所示:
在这里插入图片描述
根据 Tsuna 的测试报告,每次上下文切换都需要几十纳秒到数微秒的 CPU 时间.除此之外tlb也会应为不断的上下文切换导致缓存失效,影响效率。
什么时候会发生进程上下文切换?
1 CPU时间片用完
2 资源不足,挂起进程,等资源足够的时候,在唤醒进程
3 调用sleep函数主动挂起
4 满足高优先级的进程先执行,挂起当前进程
5 发生硬件中断,转而调用中断服务程序。
线程上下文切换
线程与进程的区别:
线程是调度的基本单位,程是资源分配的基本单位。
怎么理解呢?
cpu调度的时候任务指的就是线程,而进程提供了虚拟内存空间,全局变量等资源。
1 当进程只有一个线程时,可以认为进程就等于线程。
2 同一个进程里面的线程贡献相同的虚拟内存和全局变量等
3 线程也有自己的私有数据,比如栈和寄存器等

那么线程的上下文切换就有两种情况了:
1 前后两个线程属于不同进程。此时,因为资源不共享,所以切换过程就跟进程上下文切换是一样
2 前后两个线程属于同一个进程。此时,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据

因为上下文切换的时候消耗更小的资源,这就是多线程的优势。
中断上下文切换
为了更快的响应硬件的事件,中断是会打断正常程序的执行,转而执行中断服务程序。因为要快所有中断服务程序一般都设计成短小精悍的。因为打断了执行流程,所以要保存现在正在运行的进程的信息。这些信息包括 CPU 寄存器、内核堆栈、硬件中断参数等内核态的信息。并不需要虚拟用户空间等用户态的信息。因为中断也是会消耗CPU,切换次数过多也会耗费大量的 CPU。
查看上下文切换的工具用两个vmstat 和 pidstat -w .
vmstat主要关注:
cs(context switch)是每秒上下文切换的次数。
in(interrupt)则是每秒中断的次数。
r(Running or Runnable)是就绪队列的长度,也就是正在运行和等待 CPU 的进程数。
b(Blocked)则是处于不可中断睡眠状态的进程数。
pidstat -w 主要关注:
cswch ,表示每秒自愿上下文切换(voluntary context switches)的次数
nvcswch ,表示每秒非自愿上下文切换(non voluntary context switches)的次数。

解释一下:
自愿上下文切换,是指进程无法获取所需资源,导致的上下文切换。比如说, I/O、内存等系统资源不足时,就会发生自愿上下文切换
非自愿上下文切换,则是指进程由于时间片已到等原因,被系统强制调度,进而发生的上下文切换。比如说,大量进程都在争抢 CPU 时,就容易发生非自愿上下文切换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值