linux2.6.29 CFS调度详细分析

2023-11-06

                                                                                                            linux2.6.29 CFS调度详细分析

 众所周知,linux最新的内核采用了CFS的调度机制,网上也有不少文章对CFS调度的源码做了详细的分析,但是大部分的文章太注重细节了,所以没有把CFS的原理进行一下从整体上的概括,基于这个原因,本文要从CFS调度的基本原理以及在公平调度类的整个执行过程为主线来进行详细的说明。

   CFS(completely fair schedule),故名思议完全公平的调度,那么它到底怎么实现了完全的公平呢?既然讲公平,那就应该有个评判的标准,在这之前我们先来讲几个比较重要的概念。
调度实体(sched entiy):就是调度的对象,可以理解为进程。
虚拟运行时间(vruntime):即每个调度实体的运行时间。
公平调度队列(cfs_rq):采取公平调度的调度实体的运行队列。
   1 每个进程的weight值是如何确定的呢?
上面谈到公平的依据,CFS的公平依据就是每个调度实体的权重(weight),这个权重是有优先级来决定的,即优先级越高权重越高,linux内核采用了nice-prio-weight的一个转换关系来实现了每个调度实体权重的确定。我们来回顾,进程被创建的时候他的优先级是继承自父进程的,如果想改变有优先级,linux内核提供了几个系统调用来改变进程的nice值,从而改变权重,不如sys_nice()系统调用,下面来看一下他们之间的转换关系:
其中,MAX_RT_PRIO=100,nice的值在-20到19之前,那么优先级就在100 - 139之间。
再看prio和weight之间的转换关系,这是个经验公式。通过以上分析我们就可以通过修改nice来修改weight了,这也就回答了每个调度实体的weight是怎么确定的这个问题了吧。
2 基于这些weight,CFS又是怎么来体现公平的呢?
   CFS可实现几种不同的公平策略,这些策略是根据调度的对象的不同来区分的。
默认的是不开组调度的公平策略,即调度的单位是每个调度实体。我们来详细看一下是怎么调度的:
   假设现在系统有A,B,C三个进程,A.weight=1,B.weight=2,C.weight=3.那么我们可以计算出整个公平调度队列的总权重是cfs_rq.weight = 6,很自然的想法就是,公平就是你在重量中占的比重的多少来拍你的重要性,那么,A的重要性就是1/6,同理,B和C的重要性分别是2/6,3/6.很显然C最重要就应改被先调度,而且占用的资源也应该最多,即假设A,B,C运行一遍的总时间假设是6个时间单位的话,A占1个单位,B占2个单位,C占三个单位。这就是CFS的公平策略。
   linux内核采用了计算公式:
l         ideal_time = sum_runtime * se.weight/cfs_rq.weight
ideal_time:每个进程应该运行的时间
sum_runtime:运行队列中所有任务运行完一遍的时间
se.weight:当前进程的权重
cfs.weight:整个cfs_rq的总权重
 
这里se.weight和cfs.weight根据上面讲解我们可以算出,sum_runtime是怎们计算的呢,linux内核中这是个经验值,其经验公式是:
 
(1) sum_runtime=sysctl_sched_min_granularity * nr_running(if 进程数 > 5)
(2) sum_runtime=sysctl_sched_latency = 20 ms           (if 进程数 <= 5)
注:sysctl_sched_min_granularity =4ms
linux内核代码中是通过一个叫vruntime的变量来实现上面的原理的,即:
每一个进程拥有一个vruntime,每次需要调度的时候就选运行队列中拥有最小vruntime的那个进程来运行,vruntime在时钟中断里面被维护,每次时钟中断都要更新当前进程的vruntime,即vruntime以如下公式逐渐增长:
  (1) vruntime +=  delta* NICE_0_LOAD/ se.weight;(if curr.nice!=NICE_0_LOAD)
 (2)vruntime +=  delta;                      (if curr.nice=NICE_0_LOAD)
在每次更新完vruntime之后,将会进行一次检查,要不要设置调度位TIF_NEED_SCHED,表示要不要被抢占或自动放弃cpu,其实在没有唤醒和CPU之间的进程迁移的时候,只有当前进程主动放弃CPU这种情况,即每个进程都会运行完自己的ideal_time.
即在这里设置抢占位。
通过以上分析,我们基本上已经分析了不开组调度的情况下,进程一般的调度的原理,这里没考虑到唤醒和进程歉意的情况,在后面的文章中会详细的介绍。
 
至此,我们可能还会有几个疑问:
1 这里只是设置了TIF_NEED_SCHED位,那么谁来检查这个抢占位,来实现进程切换的呢?
  这也是在时钟中断里面做的,当时钟中断要返回的时候,会显示的调用schedule()函数,这个函数会检查TIF_NEED_SCHED有没有被置位,来决定是否进行真正的进程切换。
2 还是 A B C这三个进程,如果不考虑唤醒和进程迁移的情况,A的理想的运行时间是3个时间单位,因为只有在
             if (delta_exec > ideal_runtime)
                     resched_task(rq_of(cfs_rq)->curr);
这个时候才设置调度位,那么A运行完这段时间后有没有运行完呢?我们先来仔细分析一下这个公式:
vruntime +=  delta* NICE_0_LOAD/ se.weight;(if curr.nice!=NICE_0_LOAD)
NICE_0_LOAD是个定值,及系统默认的进程的权值
se,weight是当前进程的权重
delta是当前进程运行的时间
我们可以得出这么个关系:
vruntime与delta成正比,即当前运行时间越长vruntime增长越快
vruntime与se.weight成反比,即权重越大vunruntime增长越慢

参考来源:linuxsky.blog.chinaunix.net

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux2.6.29 CFS调度详细分析 的相关文章

  • 如何使用 Entity Framework 和 Identity 解决对象处置异常 ASP.NET Core

    我正在尝试编写一个控制器 该控制器接收来自 AJAX 调用的请求并通过 DBContext 对数据库执行一些调用 但是 当我发出命令时var user await GetCurrentUserAsynch 在对 DBContext 的任何调
  • getline 之后返回到文件开头

    所以我已经从文件中读取了所有行 while getline ifile line logic 其中 ifile 是 ifstream line 是字符串 我的问题是我现在想再次使用 getline 并且似乎无法返回到文件的开头 因为运行 c
  • Linux命令列出所有可用命令和别名

    是否有一个 Linux 命令可以列出该终端会话的所有可用命令和别名 就好像您输入 a 并按下 Tab 键一样 但针对的是字母表中的每个字母 或者运行 别名 但也返回命令 为什么 我想运行以下命令并查看命令是否可用 ListAllComman
  • perf stat中的cycles注释是什么意思

    8 014196 task clock 0 004 CPUs utilized 204 context switches 0 025 M sec 32 cpu migrations 0 004 M sec 0 page faults 0 0
  • 如何使用c#从数据桶中获取所有文档?

    如何获取数据桶中的所有文档 我尝试过一个示例 但我只能获得一个特定的文档 这是我的代码 CouchbaseClient oclient oclient new CouchbaseClient vwspace data bucket name
  • C# 中 PKCS11Interop 库的线程安全使用 [已关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在使用 PKCS11Interop 在 HSM 内执行密钥管理操作 我使用的 HSM 是 Thales PCI Express 下面是
  • 预编译头和 Visual Studio

    有没有办法设置 Visual Studio 解决方案参数 以便它只创建预编译头而不构建整个解决方案 具体来说 它是一个巨大的 C 解决方案 本身有许多项目 谢谢 仅选择 pch 创建者源文件 通常是 stdafx cpp 然后编译该文件 C
  • 无法将参数从 `const char *` 转换为 `char *`

    鉴于此代码 void group build int size std string ips Build the LL after receiving the member list from bootstrap head new memb
  • C# 中的抽象类和接口类有什么不同?

    C 中的抽象类和接口类有什么不同 An 接口不是类 它只是一个contract定义了public一个类的成员must实施 抽象类只是一个类 您从中可以cannot创建一个实例 通常您会使用它来定义一个基类 该基类定义了一些virtual方法
  • 如何调试.NET Windows Service OnStart方法?

    我用 NET 编写的代码仅在作为 Windows 服务安装时才会失败 该故障甚至不允许服务启动 我不知道如何进入 OnStart 方法 如何 调试 Windows 服务应用程序 http msdn microsoft com en us l
  • std::make_pair 与浮点数组(float2,无符号整数)

    我有一个用 float2 unsigned int 对模板化的向量 例如 std vector
  • 原子存储抛出错误

    我最近升级到了 C 11 兼容编译器 并且尝试将一些代码从 boost 更新到 c 11 标准 我在使用atomic store转换一些代码时遇到了问题 这是一些简单的测试代码 似乎会引发编译器错误 int main std shared
  • ASP.net WebForms - 在标记中使用 GetRouteUrl

    我一直在尝试弄清楚如何将路由功能与 ASP net 4 0 WebForms 一起使用 我将一条路线添加到我的路线集合中 void Application Start RegisterRoutes RouteTable Routes voi
  • 应在堆栈上分配的最大数量

    我一直在寻找堆栈溢出有关应在堆栈上分配的最大内存量的指南 我看到了堆栈与堆分配的最佳实践 但没有关于应该在堆栈上分配多少以及应该在堆上分配多少的指南 有什么想法 数字可以作为指导吗 什么时候应该在堆栈上分配 什么时候应该在堆上分配 多少才算
  • 在 C# 命令行应用程序中包含并执行 EXE

    所以我找到了一个很棒的小 EXE 命令行应用程序 我们将其称为 program exe 它输出一些我想用 C 操作的数据 我想知道是否有一种方法可以将program exe 打包 到我的Visual Studio项目文件中 这样我就可以将编
  • 如何释放字符串未使用的容量

    我正在程序中处理很多字符串 这些字符串数据在读入我的程序后的整个生命周期内都不会改变 但由于 C 字符串保留了容量 因此浪费了大量肯定不会被使用的空间 我尝试释放这些空间 但没有成功 以下是我尝试过的简单代码 string temp 123
  • 'iter' 的名称查找已更改为新的 ISO 'for' 范围

    我正在尝试编译下面的两个文件 但从编译器收到错误消息 gcc 4 3 3 Linux 错误位于带有以下符号的行 LINE WITH ERROR 我做错了什么 我该怎么改变 路易斯 g c b h b cpp b cpp In functio
  • 展开 std::reference_wrapper 的成本

    Given include
  • C# PasswordDeriveBytes:似乎 Salt 并不重要

    可能我误解了什么 以下代码通过 CryptDeriveKey 使用两种不同的盐生成两个相等的密钥 这是控制台结果 盐1 21 3e 18 a3 9a 8b 5f gt 键 da 89 ea 3d 91 08 20 98 20 e9 dc 4
  • 在 LP2844Z(Zebra 打印机)上的收据中包含 PNG [重复]

    这个问题在这里已经有答案了 我正在致力于创建一个基于 HTML5 画布的签名 绘图框 目前我们在服务器上将画布保存为PNG 但可以轻松地将base64字符串保存在数据库中 现在的问题是我们如何在打印的收据上添加签名 目前我们使用 GF 字段

随机推荐

  • 【MATLAB第62期】基于MATLAB的PSO-NN、BBO-NN、前馈神经网络NN回归预测对比

    MATLAB第62期 基于MATLAB的PSO NN BBO NN 前馈神经网络NN回归预测对比 一 数据设置 1 7输入1输出 2 103行样本 3 80个训练样本 23个测试样本 二 效果展示 NN训练集数据的R2为 0 73013 N
  • html标签总结之表格标签

    1 表格标签 表格属性 border 表格边框 写在table标签里面 数值代表边框像素 cellpadding 单元格内的空间 写在table标签里面 数值代表空间像素 cellspacing 单元格之间的空间 写在table标签里面 数
  • 线性代数——LU(LR)分解

    文章目录 定义 为什么要LU分解 为什么能做到LU分解 利用LU分解求行列式值 利用LU分解求解线性方程组 利用LU分解求逆矩阵 对角线上元素有0的情况 定义 定义 给定矩阵A 将A表示成下三角矩阵L和上三角矩阵U的乘积 称为LU分解 再进
  • 哄小姑娘的简单小密码

    老师让自由练习 给闺蜜搞个了密码表白 把她高兴的发了个朋友圈哈哈哈 include
  • QT之如何引用dll和头文件

    在QT中 我们在安装时默认安装了很多自带的类 比如画图用的QCharts等 但是当我们想使用一些其他功能的类时 我们应该怎么引入这些类呢 1 我们需要下载对应的dll和头文件 这些在网上都可以找到 以我的电脑上为例 weekday是项目的主
  • 【C++】std::thread的英文资料整理

    2023年9月10日 周日上午 这篇博客是我对网上的英文资料的整理和翻译 英文资料来自 c What exactly is an std thread Stack Overflow When you create a std thread
  • vue中使用.env文件配置全局变量

    首先根目录下创建 env或者 env production文件 生产环境 env develpment文件 开发环境 变量命名格式 键值对形式 VUE APP NAME value VUE APP 是规定的命名格式 NAME是自定义的变量名
  • 有关Flink的一些个人总结(是什么-用来做什么-有什么优势-为什么选它-解决了什么问题)

    文章目录 前言 一 Flink是什么 二 Flink用来做什么 三 Flink的优势是什么 四 为什么用Flink 五 Flink解决了什么问题 总结 前言 在大数据技术日益发展的今天 涌现出越来越多性能优异的组件 其中Spark和flin
  • 灰度重采样的方法分为_基于深度学习的着色方法介绍

    用于灰度图像着色是一种空间内插 即8比特的灰度空间扩展到24比特的RGB空间 下面以两篇文章为引子解释深度学习的应用 论文 1 是一种全自动方法从灰度产生逼真的色彩 针对着色问题的潜在不确定性 它将其作为分类任务并在训练时使用类重平衡 cl
  • openEuler的镜像地址以及换源openEulerOS.repo

    openEuler的镜像地址 https repo huaweicloud com openeuler 换源 执行如下命令 下载新的openEulerOS repo到 etc yum repos d 目录下 for aarch64 wget
  • idea导入jdbc包(java链接mysql)

    很多学生问我 idea导入jdbc怎么弄 还有人说idea社区版没法儿连接数据库 还要让我给他们破解完全版idea 下面教一下我经常用的最简单的最直接的方法 由于我的是新版UI而且还是汉化版的 所以凑活看吧 1 首先打开idea并打开需要配
  • Error in created hook (Promise/async): “Error: Network Error“ found in

    错误 Error in created hook Promise async Error Network Error axios 发送请求报错 Error Network Error at createError createError j
  • Qt for Android 配置详细 (欢迎转载)

    倒腾了近来两个礼拜 终于在实际开发机上将Qt的Demo跑起来啦 遇到好多问题但是网上都没有找比较满意的答案 所以 贴出来和各位分享一下 相互交流 有问题可以发邮件交流 sunfrank2012 google邮箱 Qt Demo 位置 htt
  • OpenWrt:目录结构

    tool和toolchain目录 是编译固件image 获取内核头文件 二进制编译器和调试器 c库文件 需要用到的通用工具 include目录 编译时的头文件索引 是一些编译用的通用脚本和include宏定义 比较重要的包括package
  • Java 输入流 Scanner 的用法

    最近在赛马网上做练习 发现很多编程题都有输入的要求 而之前在 Leetcode 上刷题并没有这个碰到这个情况 因此 特地了解了Java输入流Scanner的用法 以下是比较常用的方法 import java util Scanner 包含输
  • SQL Server数据库的增删改查

    SQL运算符 运算符 说明 求两个数或表达式相除的余数 求两个数或表达式相除的商 求两个数或表达式相加的和 求两个数或表达式相减的差 求两个数或表达式相乘的积 将一个数或表达式或变量的值赋给另一个变量 AND 当且仅当两个布尔表达式都为tr
  • SM9 用户私钥在线分发技术

    摘要 SM9 密码算法属于基于标识的密码 Identity Based Crytograph IBC 体系 它利用用户终端的标识替代或将其演化为公钥 无须公钥证书授权 Certificate Authority CA 降低了密钥资源管理和部
  • ES6之Set、WeakSet、Map、WeakMap

    Set WeakSet Map WeakMap 循序渐进 Set WeakSet Map WeakMap 一 Set 二 WeakSet 三 Map 一 Set ES6 提供了新的数据结构 Set 它类似于数组 但是成员的值都是唯一的 没有
  • AI落地:高效学习指南

    高效学习中有一个共识 学习最小可用知识 然后立马开始实践 做中学 不断获得反馈 不断在实践中改进 现实生活中 如果我们想实现这种高效学习 基本上只能找一个老师1对1指导 费用贵不说 找到合适的老师更是可遇不可求的事情 但是有了ChatGPT
  • linux2.6.29 CFS调度详细分析

    linux2 6 29 CFS调度详细分析 众所周知 linux最新的内核采用了CFS的调度机制 网上也有不少文章对CFS调度的源码做了详细的分析 但是大部分的文章太注重细节了 所以没有把CFS的原理进行一下从整体上的概括 基于这个原因 本