前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Linux系统平均负载是如何计算的?[通俗易懂]

Linux系统平均负载是如何计算的?[通俗易懂]

作者头像
全栈程序员站长
发布于 2022-10-02 06:54:39
发布于 2022-10-02 06:54:39
2.4K00
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是你们的朋友全栈君。

关于负载的计算,它的结果是包含有小数的一个浮点数,内核中是不能使用float变量的,那么这里就采用了一个整型变量的低11位来表示小数部分。那么对于数值1来说,它就是FIXED_1,也就是需要对1进行左移11bit。实际上此时这个整型变量保存的值是1024。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cat /proc/loadavg
0.43 0.58 0.65 5/7010 45102

我们通过cat命令查看负载值如上所示,它显示的是带有两个小数表示的一个浮点数,所以最后在输出这个数值时还需要做一个转换,如果从1024个值中得出这100小数部分,实际上也很简单,小学生都会计算,公式如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
小数部分 =11位的值 / 1024  * 100

内核中为了实现这个功能定义了一些宏如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#define FSHIFT      11      /* nr of bits of precision */
#define FIXED_1     (1<<FSHIFT) /* 1.0 as fixed-point */
#define LOAD_FREQ   (5*HZ+1)    /* 5 sec intervals */
#define EXP_1       1884        /* 1/exp(5sec/1min) as fixed-point */
#define EXP_5       2014        /* 1/exp(5sec/5min) */
#define EXP_15      2037        /* 1/exp(5sec/15min) */

前面介绍了单位换算的问题,后面就开始真正的主题,对于平均负载,它是如何计算的呢?

首先要先搞清楚这个概念意味着什么,实际上系统负载这个指标表示的是系统中当前正在运行的进程数量,它等于running状态的进程数 + uninterrupt状态的进程数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
load = runing tasks num + uninterrupt tasks num

那么问题来了,这个值一直都是动态变化的每秒钟都不一样,如果我们仅仅是要求平均值,那么能够想到的比较容易算的方式,假如以5秒为采样单位: … 第5秒 active nr 第10秒 active nr … 然后每次计算都累加在一起,最后除以采样次数,这样就获取到了一个平均负载值。

这样计算有一个缺点,就是我们获取到的负载值实际上并不能反应当下系统中的负载情况,因为它计算了从系统启动开始以来的平均值,无法反应当下系统的运行情况,因此系统中实际并不是这样计算的,会求最近1min,5min和15min之内的平均值,那么计算方法是怎样的呢?

对于平均算法来说有很多种实现,比如: (1)可以使用所有数据相加后处于数据个数,缺点是实时性不够好; (2)也可以去除过时数据,只保存最近的多个数据做加权平均。

前面已经介绍了第一种方式的实现缺点,那么根据平均负载的需求来看,应该要使用第2种方法才行,每次计算时需要丢弃掉1min、5min、和15min之前的数据,记录最近的数据来计算平均值,但是这种算法依然不够好,它维护的数据太多了。

因此内核采用了另外一种维护数据量更少的算法,一次指数平滑法,感兴趣的可以去网上搜索了解更多的信息。

内核在实现时引入了一个衰减系数(小于1的值),利用这个衰减系数,来达到丢弃旧数据的目的。只需要知道衰减因子、上一次计算的平均值、本次采样的值,这三个就可以计算出最新的平均值了。主要原理就是使用一个小数作为衰减系数e,从开始计算的时刻a0开始,不做衰减,那么存在如下公式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
a1 = a0 * e + a * (1 - e)
a2 = a1 * e + a * (1 - e)
a3 = a2 * e + a * (1 - e)
an = an-1 * e + a * (1 - e)

我们来看如何做到的,举个例子,如果衰减系数为0.3,那么每次在计算平均负载时,都会对旧数据乘以衰减系数,也就是上一时刻的数据占比30%,当前数据占比70%,这样就相当于是更能反映当下的系统运行情况了,每次计算周期都进行这个衰减计算,可以想象的到,距离当前2个周期的数据衰减了两次,相当于乘以30%的2次方,反复如此计算下去,那么很久远的采样数据就在当前的计算结果中无限趋近于0了。

内核中的代码实现在:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void calc_global_load(unsigned long ticks)
{ 

long active, delta;
if (time_before(jiffies, calc_load_update + 10))
return;
/* * Fold the 'old' idle-delta to include all NO_HZ cpus. */
delta = calc_load_fold_idle();
if (delta)
atomic_long_add(delta, &calc_load_tasks);
active = atomic_long_read(&calc_load_tasks);
active = active > 0 ? active * FIXED_1 : 0;
avenrun[0] = calc_load(avenrun[0], EXP_1, active);
avenrun[1] = calc_load(avenrun[1], EXP_5, active);
avenrun[2] = calc_load(avenrun[2], EXP_15, active);
calc_load_update += LOAD_FREQ;
/* * In case we idled for multiple LOAD_FREQ intervals, catch up in bulk. */
calc_global_nohz();
}

其中的:

  1. calc_load_tasks就是上面介绍时所说的runnable进程数量和uninterruptable进程数量之和。因为是SMP系统可能涉及到同步问题,因此采用atomic原子变量来保存。
  2. calc_load_update为下次采样时间,每次都需要加5*HZ,因此系统每5秒进行一次更新计算
  3. avenrun数组中保存的是1min,5min,15min时间所计算的平均值,实际上就是通过调整衰减因子来达到目的的,衰减因子越小,那么衰减越快。

在calc_load中进行一次指数平滑算法的计算:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static unsigned long
calc_load(unsigned long load, unsigned long exp, unsigned long active)
{ 

load *= exp;
load += active * (FIXED_1 - exp);
load += 1UL << (FSHIFT - 1);
return load >> FSHIFT;
}

而更新平均负载是在一个系统周期timer中实现的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void do_timer(unsigned long ticks)
1576 { 

1577     jiffies_64 += ticks;
1578     update_wall_time();
1579     calc_global_load(ticks);
1580 }

计算 calc_load_tasks 的地方:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
calc_load_fold_idle()                                       //CPU进入nohz之前会把数据进行保存
calc_load_migrate()-->calc_load_fold_active()               //CPU hotplug时,如果下线CPU需要做记录保存,加入最后更新时计算
calc_load_account_active()-->calc_load_fold_active()        //CPU没有idle,那么会执行定期更新,在每个CPU都会执行这个计算

在计算负载时: 1.每个CPU都需要定时更新 calc_load_tasks的数值,该值记录的是所有CPU上可运行和uninterruptable数量的总和(calc_load_account_active) 2.处理idle的情况,进入idle前需要保存(calc_load_fold_idle) 3.处理CPUhotplug情况,下线前需要保存值(calc_load_migrate)

最后根据calc_load_tasks执行一次global平均值计算:

1.timer中触发5HZ周期的平均值计算(calc_global_load)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/194528.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年9月12日 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
一文读懂|Linux系统平均负载
我们经常会使用 top 命令来查看系统的性能情况,在 top 命令的第一行可以看到 load average 这个数据,如下图所示:
用户7686797
2022/12/07
1.8K0
一文读懂|Linux系统平均负载
什么是系统平均负载(Load average)
  在Linux系统中,uptime、w、top等命令都会有系统平均负载load average的输出,那么什么是系统平均负载呢?
全栈程序员站长
2022/09/07
1.5K0
Linux的load average的含义
下面文章中的      “  数据是每隔5秒钟检查一次活跃的进程数,然后根据这个数值算出来的。如果这个数除以CPU的数目,结果高于5的时候就表明系统在超负荷运转了。”    具体是什么意思, 如果是cpu为8颗(双核,4核不知道如何算),目前load average 为: 20.22,20.03,18.99 应该不算超负荷运作了 ?
一见
2018/08/07
1.7K0
Linux系统Load Average解析
很多小伙伴在遇到某一接口服务性能问题时,比如说,TPS上不去、响应时间拉长、应用系统出现卡顿,某一请求出现超时等等现象,往往显得苍白无力,无从下手。
Luga Lee
2021/12/09
1.5K0
Linux系统Load Average解析
Linux 中的负载高低和 CPU 开销并不完全对应
负载是查看 Linux 服务器运行状态时很常用的一个性能指标。在观察线上服务器运行状况的时候,我们也是经常把负载找出来看一看。在线上请求压力过大的时候,经常是也伴随着负载的飙高。
开发内功修炼
2023/03/08
6840
Linux 中的负载高低和 CPU 开销并不完全对应
Linux常用性能诊断命令详解
第一行信息依次为:系统时间、运行时间、登录终端数、系统负载(三个数值分别为1分钟、5分钟、15分钟内的平均值,数值越小意味着负载越低)。
万猫学社
2022/04/22
6540
Linux常用性能诊断命令详解
深入理解Linux LA
经常和Linux打交道的童鞋都知道,load averages是衡量机器负载的关键指标,但是这个指标是怎样定义出来的呢?
大蟒传奇
2018/07/31
1.5K0
深入理解Linux LA
苏宁易购三面:写一个脚本获取Linux系统CPU的详细信息,并说出原理!
今天主要分享一个shell脚本,用来获取linux系统CPU、内存、磁盘IO等信息。
Java程序猿
2021/06/30
7380
Linux Kernel调度器的过去,现在和未来
Linux Kernel Development 一书中,关于 Linux 的进程调度器并没有讲解的很全面,只是提到了 CFS 调度器的基本思想和一些实现细节;并没有 Linux 早期的调度器介绍,以及最近这些年新增的在内核源码树外维护的调度器思想。所以在经过一番搜寻后,看到了这篇论文 A complete guide to Linux process scheduling,对 Linux 的调度器历史进行了回顾,并且相对细致地讲解了 CFS 调度器。整体来说,虽然比较啰嗦,但是对于想要知道更多细节的我来说非常适合,所以就有了翻译它的冲动。当然,在学习过程也参考了其它论文。下面开启学习之旅吧,如有任何问题,欢迎指正~
刘盼
2020/04/20
2.7K0
Linux Kernel调度器的过去,现在和未来
Linux性能检测常用的10个基本命令
本文的内容主要来自对Netflix的一篇技术博客( Linux Performance Analysis in 60,000 Milliseconds (https://medium.com/netflix-techblog/linux-performance-analysis-in-60-000-milliseconds-accc10403c55),并添加了一些自己的理解,仅供参考。
小小科
2018/09/28
5760
linux load average,Linux 平均负载 Load Average 详解[通俗易懂]
系统负载(System Load)是系统CPU繁忙程度的度量,即有多少进程在等待被CPU调度(进程等待队列的长度)。
全栈程序员站长
2022/09/09
4.2K0
How to get performance data in Android
读取文件节点/proc/loadavg,分别是1min/5min/15min内CPU的负载情况。 读取方式的代码示例:
宅男潇涧
2018/08/01
8810
How to get performance data in Android
Linux内核的进程负载均衡机制
在多核系统中,为了更好的利用多CPU并行能力,进程调度器可以将进程负载尽可能的平均到各个CPU上。再具体实现中,如何选择将进程迁移到的目标CPU,除了考虑各个CPU的负载平衡,还需要将Cache利用纳入权衡因素。同时,对于进程A唤醒进程B这个模型,还做了特殊的处理。本文分析以Centos kernel 3.10.0-975源码为蓝本。
金庆辉
2019/04/01
12.5K0
Linux系统之常用命令
环境:CentOS7X64(CentOS Linux release 7.5.1804)
尜尜人物
2020/01/15
1.5K0
Linux系统之常用命令
Linux系统下CPU使用(load average)梳理
在平时的运维工作中,当一台服务器的性能出现问题时,通常会去看当前的CPU使用情况,尤其是看下CPU的负载情况(load average)。对一般的系统来说,根据cpu数量去判断。比如有2颗cup的机器。如果平均负载始终在1.2以下,那么基本不会出现cpu不够用的情况。也就是Load平均要小于Cpu的数量。 对于cpu负载的理解,首先需要搞清楚下面几个问题: 1)系统load高不一定是性能有问题。 因为Load高也许是因为在进行cpu密集型的计算 2)系统Load高不一定是CPU能力问题或数量不够。
洗尽了浮华
2018/01/23
5.3K0
linux系统平均负载参数_变压器平均负载率怎么计算
对于一个良好的系统,平均负载应该小于CPU核心数,这意味着所有的任务都可以被及时处理,而不需要等待,反之说明任务过多,无法及时响应,长期处于这样的状态,机器存在性能问题。
全栈程序员站长
2022/09/30
7670
Linux TOP 命令详解
当前时间(date)、系统已运行时间(last reboot)、当前登录用户的数量(who )、最近5、10、15分钟内的平均负载
付威
2021/01/28
8.8K0
Linux TOP 命令详解
Linux核心调度器之周期性调度器scheduler_tick--Linux进程的管理与调度(十八)
因而内核提供了两个调度器主调度器,周期性调度器,分别实现如上工作, 两者合在一起就组成了核心调度器(core scheduler), 也叫通用调度器(generic scheduler).
233333
2018/12/04
2.8K0
Linux性能测试之性能测试指标详解
原文https://blog.csdn.net/u010521062/article/details/115908166
吾非同
2022/04/11
5.8K0
Linux性能测试之性能测试指标详解
【Linux系统内核探索】进程调度
进程调度是操作系统内核的核心功能之一,负责在多个进程之间分配CPU时间,使得系统能够同时运行多个进程。因为计算机的CPU资源有限,操作系统需要决定在任何时刻哪个进程能够使用CPU执行任务,这个过程就是进程调度。 Linux进程调度经历了多个阶段的优化,目前主流的Linux内核使用的是完全公平调度器。CFS调度器的核心思想是通过精确计算每个进程的“虚拟运行时间”来决定调度的公平性。CFS调度器不会简单依赖于时间片,而是通过调度树来快速查找下一个应运行的进程。 现代的Linux调度主要依赖于Linux的CFS调度器,在2.6版本之前主要用的是Linux内核O(1)调度算法,这次我们的重点在于Linux内核O(1)调度算法。
用户11305458
2024/11/21
1130
【Linux系统内核探索】进程调度
相关推荐
一文读懂|Linux系统平均负载
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验