为什么Linux CFS调度器没有带来惊艳的碾压效果?

2023-11-10 05:20

本文主要是介绍为什么Linux CFS调度器没有带来惊艳的碾压效果?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

但凡懂Linux内核的,都知道Linux内核的CFS进程调度算法,无论是从2.6.23将其初引入时的论文,还是各类源码分析,文章,以及Linux内核专门的图书,都给人这样一种感觉,即 CFS调度器是革命性的,它将彻底改变进程调度算法。 预期中,人们期待它会带来令人惊艳的效果。

然而这是错觉。

人们希望CFS速胜,但是分析来分析去,却只是在某些方面比O(1)调度器稍微好一点点。甚至在某些方面比不上古老的4.4BSD调度器。可是人们却依然对其趋之若鹜,特别是源码分析,汗牛塞屋!

为什么CFS对别的调度算法没有带来碾压的效果呢?

首先,在真实世界,碾压是不存在的,人与人,事与事既然被放在了同一个重量级梯队比较,其之间的差别没有想象的那么大,根本就不在谁碾压谁。不能被小说电视剧电影蒙蔽了,此外,徐晓冬大摆拳暴打雷雷也不算数,因为他们本就不是一个梯队。

任何领域,革命性的碾压式推陈出新并不是没有,但是概率极低,人们普遍的狂妄在于,总是认为自己所置身的环境正在发生着某种碾压式的变革,但其实,最终大概率不过是一场平庸。

任何领域,革命性的碾压式推陈出新并不是没有,但是概率极低,人们普遍的狂妄在于,总是认为自己所置身的环境正在发生着某种碾压式的变革,但其实,最终大概率不过是一场平庸。

最终就出现了角力,僵持。

其次,我们应该看到,CFS调度器声称它会给交互式进程带来福音,在这方面CFS确实比O(1)做得好,但是惊艳的效果来自于粉丝的认同。Linux系统交互进程本来就不多,Linux更多地被装在服务器,而在服务器看来,吞吐是要比交互响应更加重要的。

那么以交互为主的Android系统呢?我们知道,Android也是采用了CFS调度器,也有一些事BFS,为什么同样没有带来惊艳的效果呢?

我承认,2008年前后出现CFS时还没有Android,等到Android出现时,其采用的Linux内核已经默认了CFS调度器,我们看下Android版本,Linux内核版本以及发行时间的关系:

Linux内核在2.6.23就采用了CFS调度器。所以一个原因就是没有比较。Android系统上,CFS没有机会和O(1)做比较。

另外,即便回移一个O(1)调度器到Android系统去和CFS做AB,在我看来,CFS同样不会惊艳,原因很简单,Android系统几乎都是交互进程,却前台进程永远只有一个,你几乎感受不到进程的切换卡顿,换句话说,即便CFS对待交互式进程比O(1)好太多,你也感受不到,因为对于手机,平板而言,你切换APP的时间远远大于进程切换的时间粒度。

那么,CFS到底好在哪里?

简单点说,CFS的意义在于, 在一个混杂着大量计算型进程和IO交互进程的系统中,CFS调度器对待IO交互进程要比O(1)调度器更加友善和公平。理解这一点至关重要。

其实,CFS调度器的理念非常古老,就说在业界,CFS的思想早就被应用在了磁盘IO调度,数据包调度等领域,甚至最最古老的SRV3以及4.3BSD UNIX系统的进程调度中早就有了CFS的身影,可以说,Linux只是使用CFS调度器,而不是设计了CFS调度器

就以4.3BSD调度器为例,我们看一下其调度原理。

4.3BSD采用了1秒抢占制,每间隔1秒,会对整个系统进程进行优先级排序,然后找到优先级最高的投入运行,非常简单的一个思想,现在看看它是如何计算优先级的。

首先,每一个进程j均拥有一个CPU滴答的度量值Cj,每一个时钟滴答,当前在运行的进程的CPU度量值C会递增:

当一个1秒的时间区间ii过去之后,Cj被重置,该进程jj的优先级采用下面的公式计算:

可以计算,在一个足够长的时间段内,两个进程运行的总时间比例,将和它们的Base_PrioBase_Prio优先级的比例相等。

4.3BSD的优先级公平调度是CPU滴答驱动的。

现在看Linux的CFS,CFS采用随时抢占制。每一个进程j均携带一个 虚拟时钟VCj,每一个时钟滴答,当前进程k的VCk会重新计算,同时调度器选择VC最小的进程运行,计算方法非常简单:

可见, Linux的CFS简直就是4.3BSD进程调度的自驱无级变速版本!

如果你想了解CFS的精髓,上面的就是了。换成语言描述,CFS的精髓就是 “n个进程的系统,任意长的时间周期TT,每一个进程运行T/n的时间!

当然,在现实和实现中,会有80%的代码处理20%的剩余问题,比如如何奖励睡眠太久的进程等等,但是这些都不是精髓。

综上,我们总结了:

  • 现实世界很难碾压同级别的人或事。

  • 大量的Linux服务器不需要照顾交互进程,CFS优势无法凸显。

  • 大量的Android系统没有和O(1)同台竞技的机会。

  • 大量的Android系统交互进程很难感知进程调度这件事。

  • CFS调度思想古已有之。

所以无论从概念还是从效果,Linux CFS调度器均没有带来令人眼前一亮的哇塞效果。但是还缺点什么。嗯,技术上的解释。

分析和解释任何一个机制之前,必然要先问,这个机制的目标是什么,它要解决什么问题,这样才有意义。而不能仅仅是明白了它是怎么工作的。

那么Linux CFS调度器被采用,它的目标是解决什么问题的呢?它肯定是针对O(1)算法的一个问题而被引入并取代O(1),该问题也许并非什么臭名昭著,但是确实是一枚钉子,必须拔除。

O(1)调度器的本质问题在于 进程的优先级和进程可运行的时间片进行了强映射!

也就是说,给定一个进程优先级,就会计算出一个时间片与之对应,我们忽略奖惩相关的动态优先级,看一下原始O(1)算法中一个进程时间片的计算:

#define BASE_TIMESLICE(p) (MIN_TIMESLICE + /
((MAX_TIMESLICE - MIN_TIMESLICE) * /
(MAX_PRIO-1 - (p)->static_prio) / (MAX_USER_PRIO-1)))static inline unsigned int task_timeslice(task_t *p)
{return BASE_TIMESLICE(p);
}

直观点显示:

针对上述问题,2.6内核的O(1)O(1)引入了双斜率来解决:

static unsigned int task_timeslice(task_t *p)
{if (p->static_prio < NICE_TO_PRIO(0))return SCALE_PRIO(DEF_TIMESLICE*4, p->static_prio);elsereturn SCALE_PRIO(DEF_TIMESLICE, p->static_prio);
}

直观图示如下:

貌似问题解决了,但是如果单单揪住上图的某一个优先级子区间来看,还是会有问题,这就是相对优先级的问题。我们看到,高优先级的时间片是缓慢增减的,而低优先级的时间片却是陡然增减,同样都是相差同样优先级的进程,其优先级分布影响了它们的时间片分配。

本来是治瘸子,结果腿好了,但是胳臂坏了。

本质上来讲,这都源自于下面两个原因:

固定的优先级映射到固定的时间片。

相对优先级和绝对优先级混杂。

那么这个问题如何解决?

优先级和时间片本来就是两个概念,二者中间还得有个变量沟通才可以。优先级高只是说明该进程能运行的久一些,但是到底久多少,并不是仅仅优先级就能决定的,还要综合考虑,换句话距离来说,如果只有一个进程,那么即便它优先级再低,它也可以永久运行,如果系统中有很多的进程,即便再高优先级的进程也要让出一些时间给其它进程。

所以,考虑到系统中总体的进程情况,将优先级转换为权重,将时间片转换为份额,CFS就是了。最终的坐标系应该是权重占比/时间片坐标系而不是权重(或者优先级)/时间片。应该是这个平滑的样子:

看来,Linux CFS只是为了解决O(1)O(1)中一个“静态优先级/时间片映射”问题的,那么可想而知,它又能带来什么惊艳效果呢?这里还有个“但是”,这个O(1)O(1)调度器的问题其实在计算密集型的守护进程看来,并不是问题,反而是好事,毕竟高优先级进程可以无条件持续运行很久而不切换。这对于吞吐率的提高,cache利用都是有好处的。无非也就侵扰了交互进程呗,又有何妨。

当然,使用调优CFS的时候,难免也要遇到IO睡眠奖惩等剩余的事情去设计一些trick算法,这破费精力。

对了,还要设置你的内核为HZ1000哦,这样更能体现CFS的平滑性,就像它宣称的那样。我难以想象,出了Ubuntu,Suse等花哨的桌面发行版之外,还有哪个Linux需要打开HZ1000,服务器用HZ250不挺好吗?

关于调度的话题基本就说完了,但是在进入下一步固有的喷子环节之前,还有两点要强调:

  1. CFS的时间片是动态的,是系统负载均衡以及其优先级的函数,这便可以把进程调度动态适应到系统最佳,以节省切换开销。

  2. 即便是到了多核时代,对于实时进程依然像单核时代那般严格遵循最优先调度。

我还是想说,在调度器设计方面,大部分的人们关注点错了!

在CPU核数越来越多的时代,人们更应该关心把进程调度到哪里CPU核上而不是某个CPU核要运行哪个进程

单核时代一路走过来的Linux,发展迅猛,这无可厚非,但是成就一个操作系统内核的并不单单是技术,还有别的。这些当然程序员们很不爱听,程序员最烦非技术方面的东西了,程序员跟谁都比写代码,程序员特别喜欢喷领导不会写代码云云。

Linux在纯技术方面并不优秀,Linux总体上优秀的原因是因为有一群非代码不明志的程序员在让它变得越来越优秀,另一方面还要归功于开源和社区。Linux的学习门槛极低,如果一个公司能不费吹灰之力招聘到一个Linux程序员的话,那它干嘛还要费劲九牛二虎之力去招聘什么高端的BSD程序员呢?最终的结果就是,Linux用的人极多,想换也换不掉了。

但无论如何也没法弥补Linux内核上的一些原则性错误。

Linux内核还是以原始的主线为base,以讲Linux内核的书为例,经典的Robert Love的《Linux内核设计与实现》,以及《深入理解Linux内核》,在讲进程调度的时候,关于多核负载均衡的笔墨都是少之又少甚至没有,如此经典的著作把很多同好引向了那万劫不复的代码深渊。于是乎,铺天盖地的CFS源码分析纷至沓来。

但其实,抛开这么一个再普通不过的Linux内核,现代操作系统进入了多核时代,其核心正是在cache利用上的革新,带来的转变就是进程调度和内存管理的革新。review一下Linux内核源码,这些改变早就已经表现了出来。

可悲的是,关于Linux内核的经典书籍却再也没有更新,所有的从传统学校出来的喜欢看书学习的,依然是抱着10年前的大部头在啃。

当然了,Linux内核作为一个代码来讲,它是普适的,所以社区很难看到且关注单单是多核的问题,社区关注的最多的是可维护性,而不是性能。Linux新特性在128MB内存的i386机器上跑没有问题,那就是OK的。只要不是80%以上的人遭遇的新问题,社区是从不care的,同时,正因为如此,社区还会引入bug,这也是令人想叹息都不能叹息。

我的看法吧,社区只是一个一切以代码为准绳的程序员社区,社区不会过于关注体系结构的发展和新特性,这些都是厂商的事情。

回到进程调度的话题,正因为Linux一直在关注调度算法本身以及其实现的代码,才会出现The Linux Scheduler: a Decade of Wasted Cores,这篇十分中肯的paper:

http://www.ece.ubc.ca/~sasha/papers/eurosys16-final29.pdf

同样,我一向喷的TCP也是如此,人们关注TCP的实现代码本身,才会让它越来越复杂,然后越来越脆弱,也许你会说这就是进化,但是趁着万劫不复前,不是还有回炉的机会吗?还没有进化到必须继续进化的地步吧。如果站在外面看且具有强制措施,估计早就没有垃圾TCP了吧。

浙江温州皮鞋湿,下雨进水不会胖。

这篇关于为什么Linux CFS调度器没有带来惊艳的碾压效果?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/380568

相关文章

豆包 MarsCode 不允许你还没有女朋友

在这个喧嚣的世界里,爱意需要被温柔地唤醒。为心爱的她制作每日一句小工具,就像是一场永不落幕的浪漫仪式,每天都在她的心田播撒爱的种子,让她的每一天都充满甜蜜与期待。 背景 在这个瞬息万变的时代,我们都在寻找那些能让我们慢下来,感受生活美好的瞬间。为了让这份浪漫持久而深刻,我们决定为女朋友定制一个每日一句小工具。这个工具会在她意想不到的时刻,为她呈现一句充满爱意的话语,让她的每一天都充满惊喜和感动

linux-基础知识3

打包和压缩 zip 安装zip软件包 yum -y install zip unzip 压缩打包命令: zip -q -r -d -u 压缩包文件名 目录和文件名列表 -q:不显示命令执行过程-r:递归处理,打包各级子目录和文件-u:把文件增加/替换到压缩包中-d:从压缩包中删除指定的文件 解压:unzip 压缩包名 打包文件 把压缩包从服务器下载到本地 把压缩包上传到服务器(zip

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

搭建Kafka+zookeeper集群调度

前言 硬件环境 172.18.0.5        kafkazk1        Kafka+zookeeper                Kafka Broker集群 172.18.0.6        kafkazk2        Kafka+zookeeper                Kafka Broker集群 172.18.0.7        kafkazk3

4B参数秒杀GPT-3.5:MiniCPM 3.0惊艳登场!

​ 面壁智能 在 AI 的世界里,总有那么几个时刻让人惊叹不已。面壁智能推出的 MiniCPM 3.0,这个仅有4B参数的"小钢炮",正在以惊人的实力挑战着 GPT-3.5 这个曾经的AI巨人。 MiniCPM 3.0 MiniCPM 3.0 MiniCPM 3.0 目前的主要功能有: 长上下文功能:原生支持 32k 上下文长度,性能完美。我们引入了

防近视护眼台灯什么牌子好?五款防近视效果好的护眼台灯推荐

在家里,灯具是属于离不开的家具,每个大大小小的地方都需要的照亮,所以一盏好灯是必不可少的,每个发挥着作用。而护眼台灯就起了一个保护眼睛,预防近视的作用。可以保护我们在学习,阅读的时候提供一个合适的光线环境,保护我们的眼睛。防近视护眼台灯什么牌子好?那我们怎么选择一个优秀的护眼台灯也是很重要,才能起到最大的护眼效果。下面五款防近视效果好的护眼台灯推荐: 一:六个推荐防近视效果好的护眼台灯的

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念