Linux 2.6 完全公平调度算法CFS(Completely Fair Scheduler) 分析

转会http://www.ibm.com/developerworks/cn/linux/l-completely-fair-scheduler/index.html?

ca=drs-cn-0125

Linux 调度器简史

早期的 Linux 调度器使用了最低的设计,它显然不关注具有非常多处理器的大型架构,更不用说是超线程了。1.2 Linux 调度器使用了环形队列用于可执行的任务管理。使用循环调度策略。

此调度器加入和删除进程效率非常高(具有保护结构的锁)。简而言之,该调度器并不复杂可是简单快捷。
Linux 版本号 2.2 引入了调度类的概念,同意针对实时任务、非抢占式任务、非实时任务的调度策略。 2.2 调度器还包含对称多处理 (SMP) 支持。


2.4 内核包括了相对简单的调度器,按 O(N) 的时间间隔运行(在调度事件期间它会迭代每一个任务)。

2.4 调度器将时间切割成 epoch。每一个 epoch 中,每一个任务同意运行到其时间切片用完。

假设某个任务没有使用其全部的时间切片。那么 剩余时间切片的一半将被加入到新时间切片使其在下个 epoch 中能够运行更长时间。

调度器仅仅是迭代任务。应用 goodness 函数(指标)决定以下运行哪个任务。

虽然这样的方法比較简单,可是却比較低效、缺乏可扩展性并且不适合用在实时系统中。它还缺少利用新硬件架构(比方多核处理器)的能力。
早期的 2.6 调度器,叫做 O(1) 调度器,它旨在解决 2.4 调度器存在的问题 — 该调度器不须要迭代整个任务列表来确定要调度的下一个任务(因此得名 O(1),这意味着它效率更高,扩展性更好)。O(1) 调度器跟踪执行队列中可执行的任务(实际上,每一个优先级水平有两个执行队列 — 一个用于活动任务。一个用于过期任务)。 这意味着要确定接下来执行的任务,调度器仅仅需按优先级将下一个任务从特定活动的执行队列中取出就可以)。 O(1) 调度器扩展性更好并且包括交互性,提供了大量启发用于确定任务是受 I/O 限制还是受处理器限制。 可是 O(1) 调度器在内核中非常笨拙。须要大量代码计算启发。难以管理而且对于纯粹主义者而言未能体现算法的本质。

为了解决 O(1) 调度器面临的问题以及应对其它外部压力, 须要改变某些东西。这样的改变来自 Con Kolivas 的内核补丁。当中包括他的 Rotating Staircase Deadline Scheduler (RSDL), 这包括了他在 staircase 调度器方面的早期工作。这些工作的成果就是一个设计简单的调度器,包括了公平性和界限内延迟。

Kolivas 的调度器吸引了非常多人(而且非常多人呼吁将其包括在眼下的 2.6.21 主流内核中),非常显然调度器的变革即将发生。 Ingo Molnar,O(1) 调度器的创造者,然后环绕 Kolivas 的一些思想开发了基于 CFS 的调度器。我们来剖析一下 CFS。从较高的层次上看看它是怎样执行的。

------------------------------------------------------------------------------------------------------------------------------

CFS 概述

CFS 背后的主要想法是维护为任务提供处理器时间方面的平衡(公平性)。这意味着应给进程分配相当数量的处理器。

分给某个任务的时间失去平衡时(意味着一个或多个任务相对于其它任务而言未被给予相当数量的时间)。应给失去平衡的任务分配时间,让其运行。

要实现平衡,CFS 在叫做虚拟执行时 的地方维持提供给某个任务的时间量。任务的虚拟执行时越小。 意味着任务被同意訪问server的时间越短 — 其对处理器的需求越高。

CFS 还包括睡眠公平概念以便确保那些眼下没有执行的 任务(比如。等待 I/O)在其终于须要时获得相当份额的处理器。

可是与之前的 Linux 调度器不同,它没有将任务维护在执行队列中,CFS 维护了一个以时间为顺序的红黑树(參见图 1)。

 红黑树 是一个树,具有非常多有趣、实用的属性。首先,它是自平衡的,这意味着树上没有路径比不论什么其它路径长两倍以上。

第二,树上的执行按 O(log n) 时间发生(当中 n 是树中节点的数量)。这意味着您能够高速高效地插入或删除任务。

图 1. 红黑树演示样例
红黑树演示样例

任务存储在以时间为顺序的红黑树中(由 sched_entity 对象表示),对处理器需求最多的任务 (最低虚拟执行时)存储在树的左側,处理器需求最少的任务(最高虚拟执行时)存储在树的右側。 为了公平。调度器然后选取红黑树最左端的节点调度为下一个以便保持公平性。

任务通过将其执行时间加入到虚拟执行时, 说明其占用 CPU 的时间,然后假设可执行。再插回到树中。这样,树左側的任务就被给予时间执行了,树的内容从右側迁移到左側以保持公平。

因此,每一个可执行的任务都会追赶其它任务以维持整个可执行任务集合的执行平衡。

------------------------------------------------------------------------------------------------------------------------------

CFS 内部原理

Linux 内的全部任务都由称为 task_struct 的任务结构表示。该结构(以及其它相关内容)完整地描写叙述了任务并包含了任务的当前状态、其堆栈、进程标识、优先级(静态和动态)等等。

您能够在 ./linux/include/linux/sched.h 中找到这些内容以及相关结构。 可是由于不是全部任务都是可执行的。您在 task_struct 中不会发现不论什么与 CFS 相关的字段。 相反,会创建一个名为 sched_entity 的新结构来跟踪调度信息(參见图 2)。

图 2. 任务和红黑树的结构层次
任务和红黑树的结构层次

各种结构的关系如 图 2 所看到的。

树的根通过 rb_root 元素通过 cfs_rq 结构(在 ./kernel/sched.c 中)引用。红黑树的叶子不包括信息。可是内部节点代表一个或多个可执行的任务。

红黑树的每一个节点都由 rb_node 表示,它仅仅包括子引用和父对象的颜色。

 rb_node 包括在sched_entity 结构中,该结构包括 rb_node 引用、负载权重以及各种统计数据。最重要的是, sched_entity 包括 vruntime(64 位字段),它表示任务执行的时间量,并作为红黑树的索引。 最后,task_struct 位于顶端,它完整地描写叙述任务并包括 sched_entity 结构。

就 CFS 部分而言,调度函数很easy。 在 ./kernel/sched.c 中。您会看到通用 schedule() 函数,它会先抢占当前执行任务(除非它通过yield() 代码先抢占自己)。注意 CFS 没有真正的时间切片概念用于抢占,由于抢占时间是可变的。

当前执行任务(如今被抢占的任务)通过对 put_prev_task 调用(通过调度类)返回到红黑树。 当 schedule 函数開始确定下一个要调度的任务时,它会调用 pick_next_task函数。此函数也是通用的(在 ./kernel/sched.c 中)。但它会通过调度器类调用 CFS 调度器。 CFS 中的 pick_next_task 函数能够在 ./kernel/sched_fair.c(称为 pick_next_task_fair())中找到。 此函数仅仅是从红黑树中获取最左端的任务并返回相关 sched_entity。通过此引用,一个简单的 task_of() 调用确定返回的 task_struct 引用。通用调度器最后为此任务提供处理器。

------------------------------------------------------------------------------------------------------------------------------

优先级和 CFS

CFS 不直接使用优先级而是将其用作同意任务运行的时间的衰减系数。

低优先级任务具有更高的衰减系数。而高优先级任务具有较低的衰减系数。

这意味着与高优先级任务相比,低优先级任务同意任务运行的时间消耗得更快。 这是一个绝妙的解决方式,能够避免维护按优先级调度的运行队列。

CFS 组调度

CFS 还有一个有趣的地方是组调度 概念(在 2.6.24 内核中引入)。组调度是还有一种为调度带来公平性的方式,尤其是在处理产生非常多其它任务的任务时。 如果一个产生了非常多任务的server要并行化进入的连接(HTTP server的典型架构)。不是全部任务都会被统一公平对待, CFS 引入了组来处理这样的行为。产生任务的server进程在整个组中(在一个层次结构中)共享它们的虚拟执行时,而单个任务维持其自己独立的虚拟执行时。这样单个任务会收到与组大致同样的调度时间。

您会发现 /proc 接口用于管理进程层次结构,让您对组的形成方式有全然的控制。使用此配置。您能够跨用户、跨进程或其变体分配公平性。

调度类和域

与 CFS 一起引入的是调度类概念(能够回想 图 2)。每一个任务都属于一个调度类,这决定了任务将怎样调度。 调度类定义一个通用函数集(通过 sched_class),函数集定义调度器的行为。

比如,每一个调度器提供一种方式, 增加要调度的任务、调出要执行的下一个任务、提供给调度器等等。

每一个调度器类都在一对一连接的列表中彼此相连,使类能够迭代(比如。 要启用给定处理器的禁用)。一般结构如图 3 所看到的。注意,将任务函数增加队列或脱离队列仅仅需从特定调度结构中增加或移除任务。 函数 pick_next_task 选择要执行的下一个任务(取决于调度类的详细策略)。

图 3. 调度类图形视图
调度类图形视图

可是不要忘了调度类是任务结构本身的一部分(參见 图 2)。这一点简化了任务的操作,不管其调度类怎样。比如, 下面函数用 ./kernel/sched.c 中的新任务抢占当前执行任务(当中 curr 定义了当前执行任务。 rq 代表 CFS 红黑树而 p 是下一个要调度的任务):

static inline void check_preempt( struct rq *rq, struct task_struct *p )
{rq->curr->sched_class->check_preempt_curr( rq, p );
}

假设此任务正使用公平调度类,则 check_preempt_curr() 将解析为 check_preempt_wakeup()

您能够在 ./kernel/sched_rt.c, ./kernel/sched_fair.c 和 ./kernel/sched_idle.c 中查看这些关系。

调度类是调度发生变化的还有一个有趣的地方,可是随着调度域的添加。功能也在添加。 这些域同意您出于负载平衡和隔离的目的将一个或多个处理器按层次关系分组。 一个或多个处理器可以共享调度策略(并在其之间保持负载平衡)或实现独立的调度策略从而有益隔离任务。

其它调度器

继续研究调度,您将发现正在开发中的调度器将会突破性能和扩展性的界限。Con Kolivas 没有被他的 Linux 经验羁绊。他开发出了还有一个 Linux 调度器。其缩写为:BFS。

该调度器据说在 NUMA 系统以及移动设备上具有更好的性能。 而且被引入了 Android 操作系统的一款衍生产品中。




版权声明:本文博客原创文章。博客,未经同意,不得转载。

转载于:https://www.cnblogs.com/mfrbuaa/p/4641240.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/290917.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在计算机技术方面用英语怎么说,“计算机应用技术”用英语怎么说?

计算机应用技术 :1. Computer Applications Technology中国搜学网-学苑论坛 - 教育话题 - 学习交流 ... ...专利文献检索 The Searches of Patent Literature计算机应用技术 Computer Applications Technology精密电磁测量 Precise Electromagnetic Measurement ...2. Computer…

同页面多UpdatePanel的单独刷新

<!--UpdateMode"Conditional"设置为不共用的UpdatePanel--><asp:UpdatePanel runat"server" ID"up1" UpdateMode"Conditional"><ContentTemplate><asp:Button runat"server" ID"Button1" On…

linux之nautilus .命令浏览当前文件目录

1、比如我们在终端目前想打开这个路径下的文件目录&#xff0c;我们如果再去更加路径一个一个的打&#xff0c;就太浪费时间了&#xff0c;我们可以在终端这个路径下输入下面的命令就可以 ~/Desktop$ nautilus . 2、效果如下图

C# 异步与Windows应用程序

把 async 关键字用于 UWP 应用程序&#xff0c;需要注意&#xff0c;在 UI 线程中调用 await 之后&#xff0c;当异步方法返回时&#xff0c;将默认返回到 UI 线程中。这便于在异步方法完成后更新 UI 元素。注意为了创建 UWP 应用程序&#xff0c;需要 Windows 10&#xff0c;W…

重装系统后恢复oracle数据

2019独角兽企业重金招聘Python工程师标准>>> 由于前段时间重装了系统&#xff0c;今天重装了数据库oracle XE版本&#xff0c;用“移花接木”的手段将新装oracle的目录用原有目录直接给覆盖&#xff0c;于是顺利的启动了oracle服务&#xff0c;然后又打开plsql deve…

使用eclipse运行mapreduce程序

今天使用http://www.cnblogs.com/xia520pi/archive/2012/05/16/2504205.html上的方式搭建一个基于Eclipse的mapreduce开发环境&#xff0c;在运行WordCount例子时出现错误&#xff0c;经过检查后才发现&#xff0c;装了hadoop2.0插件的Eclipse在右击选择“run on hadoop”时不会…

java Split 用法

在java.lang包中有String.split()方法,返回是一个数组 我在应用中用到一些,给大家总结一下,仅供大家参考: 1、如果用“.”作为分隔的话,必须是如下写法,String.split("\\."),这样才能正确的分隔开,不能用String.split("."); 2、如果用“|”作为分隔的话,必…

html三列布局源码,HTML三列布局 - 黄柳淞的个人页面 - OSCHINA - 中文开源技术交流社区...

1.三列布局1三列布局body{padding: 0;margin: 0;}.left{width:33.3%;height: 500px;background-color: #ccc;float: left;}.middle{width:33.3%;height: 500px;background-color: #bbb;float: left;}.right{width:33.3%;height: 500px;background-color: #aaa;float: left;}33.…

Android之如何用dextra.ELF64查看安卓手机“设置“图标的源代码

1、找到手机“设置”图标的包名 adb shell dumpsys activity top 得到包名: com.android.settings 2、拉下odex文件 1)、通过包名得到odex文件 adb shell pm list pakcage -f | grep com.android.settings 2)、得到结果 package:/system/priv-app/Settings/Settings.apk=co…

unity3d Json解析工具类

使用到的是Newtonsoft.Json动态库&#xff0c;下载地址&#xff1a;http://www.newtonsoft.com/json using Newtonsoft.Json; using System.Collections.Generic; using System.IO;/// <summary> /// Json帮助类 /// </summary> public class JsonHelper {/// <…

.NET6之MiniAPI(二十):实体验证FluentValidation

为了验证api post上来的数据的有效性&#xff0c;我们可以引入FluentValidation(详见https://fluentvalidation.net)。在asp.net mvc中&#xff0c;使用的是模型验证&#xff0c;通过在实体类上添加特性达到验证效果。FluentValidation的原理是通过实现AbstractValidator<T&…

nagios的搭建及配置----(中)

上篇文章写到了我们布置的nagios监控本机的状态&#xff0c;下面我们来看下nagios监控服务器状态的配置。至于为什么要这么配置&#xff0c;大家可以自行去百度下看看使用NRPE插件实现对remote server 进行监控&#xff0c;远程服务器配置1&#xff0c;编译安装nagios-plugin&a…

计算机整个文稿应用回顾主题,《计算机应用基础》精品课程电子教案-PowerPoint 2003...

一&#xff0e;回顾上次课内容(提问方式)对于幻灯片的切换、配色方案的使用、母版的使用用实例进行提问&#xff0c;通过学生的操作了解学生掌握的情况&#xff0c;并加强学生的实践操作能力。二、新课教学(讲解法、示范法)5.6.1幻灯片切换具体操作方法如下&#xff1a;在【幻灯…

linux之so文件、a文件、o文件的区别

1、o文件 o 就相当于windows里的obj文件 ,一个.c或.cpp文件对应一个.o文件 .o 文件是源码编译出的二进制文件。 你先得了解从源代码到可执行文件的过程。以一个简单的add函数源文件为例。 int add(int a,int b) {return a+b; } 先预处理为.i文件gcc -E add.c -o add.i 再编译为…

【F大说】Flash的那些坑

转载自F大的自言自语←_←创建控件类时&#xff0c;基类不能用源码创建控件类时&#xff0c;基类要以swc方式提供&#xff08;不能用源码&#xff09;&#xff0c;否则控件中所包含的子元件实例名将被添加到基类&#xff0c;而不是控件类中去。调用gotoAndStop会导致帧代码插队…

iNeuOS工业互联网操作系统,顺利从NetCore3.1升级到Net6的过程汇报,发布3.7版本...

目 录1..... 概述... 12..... 升级的工程... 33..... 升级的代码差异... 44..... 系统运行... 51. 概述我们团队一直在工业领域从事实时系统和业务系统的开发与集成工作&#xff0c;开发语言使用过C51/C/VB/VC/C#(Net Framework)/C#(Netcore3.1)/C#(NET6)。前几天微软发…

软件设计和设计的问题

先感概一句, 软件设计是一个不太容易的事情&#xff0c;尤其历史需要兼容新需求的问题。 软件设计 软件设计包括很多&#xff0c;软件架构&#xff0c;软件结构&#xff0c;数据库设计。 软件不是从0开始的&#xff0c;一般都会有一些支撑组件&#xff0c;尤其现在的web程序&am…

郑州升达经贸管理学院计算机科学与技术,郑州升达经贸管理学院计算机科学与技术专业2016年在福建理科高考录取最低分数线...

类似问题答案郑州升达经贸管理学院计算机科学与技术专业2016年在吉林理科高考录取最低分数线学校 地 区 专业 年份 批次 类型 分数 郑州升达经贸管理学院 吉林 计算机科学与技术 2016 二批 理科 336 学校 地 区 专业 年份 批次 类型 分数 郑州升达经贸管理学院 吉林 计算机科学…

Android之INSTALL_FAILED_UPDATE_INCOMPATIBLE(pacakge:...do not match the previously installed version)

1、问题&#xff1a; adb install -r ***.apk 出现下面错误 INSTALL_FAILED_UPDATE_INCOMPATIBLE(pacakge:...do not match the previously installed version&#xff1b;ignoring) 2、解决办法&#xff1a; 用ApkHelp工具&#xff0c;检验这2g个apk,发现签名不一样&#…

0714M

/*************************************************************************> File Name: code/2015summer/0714/M.cpp> Author: 111qqz> Email: rkz2013126.com > Created tim: 2015年07月14日 星期二 11时37分51秒******************************************…