`
yiyeqinghuasoon
  • 浏览: 638806 次
文章分类
社区版块
存档分类
最新评论

linux内核调度算法(2)--CPU时间片如何分配

 
阅读更多

内核在微观上,把CPU的运行时间分成许多分,然后安排给各个进程轮流运行,造成宏观上所有的进程仿佛同时在执行。双核CPU,实际上最多只能有两个进程在同时运行,大家在top、vmstat命令里看到的正在运行的进程,并不是真的在占有着CPU哈。

所以,一些设计良好的高性能进程,比如nginx,都是实际上有几颗CPU,就配几个工作进程,道理就在这。比如你的服务器有8颗CPU,那么nginx worker应当只有8个,当你多于8个时,内核可能会放超过多个nginx worker进程到1个runqueue里,会发生什么呢?就是在这颗CPU上,会比较均匀的把时间分配给这几个nginx worker,每个worker进程运行完一个时间片后,内核需要做进程切换,把正在运行的进程上下文保存下来。假设内核分配的时间片是100ms,做进程切换的时间是5ms,那么进程性能下降还是很明显的,跟你配置的worker有关,越多下降得越厉害。

当然,这是跟nginx的设计有关的。nginx是事件驱动的全异步进程,本身设计上就几乎不存在阻塞和中断,nginx的设计者就希望每一个nginx worker可以独占CPU的几乎全部时间片,这点就是nginx worker数量配置的依据所在。


当然,实际的运行进程里,大部分并不是nginx这种希望独占CPU全部时间片的进程,许多进程,比如vi,它在很多时间是在等待用户输入,这时vi在等待IO中断,是不占用时间片的,内核面对多样化的进程,就需要技巧性的分配CPU时间片了。


内核分配时间片是有策略和倾向性的。换句话说,内核是偏心的,它喜欢的是IO消耗型进程,因为这类进程如果不能及时响应,用户就会很不爽,所以它总会下意识的多分配CPU运行时间给这类进程。而CPU消耗进程内核就不太关心了。这有道理吗?太有了,CPU消耗型慢一点用户感知不出来,电信号和生物信号运转速度差距巨大。虽然内核尽量多的分配时间片给IO消耗型进程,但IO消耗进程常常在睡觉,给它的时间片根本用不掉。很合理吧?


那么内核具体是怎么实现这种偏心呢?通过动态调整进程的优先级,以及分配不同长短的CPU时间处来实现。先说内核如何决定时间片的长度。

对每一个进程,有一个整型static_prio表示用户设置的静态优先级,内核里它与nice值是对应的。看看进程描述结构里的static_prio成员。

nice值是什么?其实就是优先级针对用户进程的另一种表示法,nice的取值范围是-20到+19,-20优先级最高,+19最低。上篇曾经说过,内核优先级共有140,而用户能够设置的NICE优先级如何与这140个优先级对应起来呢?看代码:


可以看到,MAX_PRIO就是140,也就是内核定义的最大优先级了。


而MAX_USER_PRIO就是40,意指,普通进程指定的优先级别最多40,就像前面我们讲的那样-20到+19。



nice值是-20表示最高,对应着static_prio是多少呢?NICE_TO_PRIO(0)就是120,NICE_TO_PRIO(-20)就是100。


当该进程刚被其父进程fork出来时,是平分其父进程的剩余时间片的。这个时间片执行完后,就会根据它的初始优先级来重新分配时间片,优先级为+19时最低,只分配最小时间片5ms,优先级为0时是100ms,优先级是-20时是最大时间片800ms。我们看看内核是如何计算时间片长度的,大家先看下task_timeslice时间片计算函数:


这里有一堆宏,我们把宏依次列出看看它们的值:

所以,DEF_TIMESLICE是100。假设nice值是-20,那么static_prio就是100,那么SCALE_PRIO(100*4, 100)就等于800,意味着最高优先级-20情形下,可以分到时间片是800ms,如果nice值是+19,则只能分到最小时间片5ms,nice值是默认的0则能分到100ms。


貌似时间片只与nice值有关系。实际上,内核会对初始的nice值有一个-5到+5的动态调整。这个动态调整的依据是什么呢?很简单,如果CPU用得多的进程,就把nice值调高点,等价于优先级调低点。CPU用得少的进程,认为它是交互性为主的进程,则会把nice值调低点,也就是优先级调高点。这样的好处很明显,因为1、一个进程的初始优先值的设定未必是准确的,内核根据该进程的实时表现来调整它的执行情况。2、进程的表现不是始终如一的,比如一开始只是监听80端口,此时进程大部分时间在sleep,时间片用得少,于是nice值动态降低来提高优先级。这时有client接入80端口后,进程开始大量使用CPU,这以后nice值会动态增加来降低优先级。


思想明白了,代码实现上,优先级的动态补偿到底依据什么呢?effective_prio返回动态补偿后的优先级,注释非常详细,大家先看下。


可以看到bonus会对初始优先级做补偿。怎么计算出这个BONUS的呢?


可以看到,进程描述符里还有个sleep_avg,动态补偿完全是根据它的值来运作的。sleep_avg就是关键了,它表示进程睡眠和运行的时间,当进程由休眠转到运行时,sleep_avg会加上这次休眠用的时间。在运行时,每运行一个时钟节拍sleep_avg就递减直到0为止。所以,sleep_avg越大,那么就会给到越大的动态优先级补偿,达到MAX_SLEEP_AVG时会有nice值-5的补偿。


内核就是这么偏爱交互型进程,从上面的优先级和时间片分配上都能看出来。实际上,内核还有方法对交互型进程搞优待。上篇说过,runqueue里的active和expired队列,一般的进程时间片用完后进expired队列,而对IO消耗的交互型进程来说,则会直接进入active队列中,保证高灵敏的响应,可见什么叫万千宠爱于一身了。




分享到:
评论

相关推荐

    Linux2.6内核标准教程(共计8-- 第1个)

    4.5.3 时间片分配 181 4.5.4 进程调度时机 182 4.6 进程切换过程分析 183 4.6.1 选取合适进程 183 4.6.2 完成上下文切换 184 4.7 空闲进程的初始化 187 4.7.1 空闲进程的内核态栈 187 4.7.2 空闲进程...

    进程的优先级与调度策略—Linux

    概述1.1 进程优先级1.2 普通进程的调度1.2.1 静态优先级和基本时间片1.2.2 动态优先级和平均睡眠1.3 实时进程的调度1.4 内核空间优先级2.调度策略2.1 进程的抢占2.2 调度算法2.3 O(1)调度2.4 调度模型——机制与策略...

    Linux2.6内核标准教程(共计8--第6个)

    4.5.3 时间片分配 181 4.5.4 进程调度时机 182 4.6 进程切换过程分析 183 4.6.1 选取合适进程 183 4.6.2 完成上下文切换 184 4.7 空闲进程的初始化 187 4.7.1 空闲进程的内核态栈 187 4.7.2 空闲进程...

    Linux2.6内核标准教程(共计8--第8个)

    4.5.3 时间片分配 181 4.5.4 进程调度时机 182 4.6 进程切换过程分析 183 4.6.1 选取合适进程 183 4.6.2 完成上下文切换 184 4.7 空闲进程的初始化 187 4.7.1 空闲进程的内核态栈 187 4.7.2 空闲进程...

    Linux2.6内核标准教程(共计8--第3个)

    4.5.3 时间片分配 181 4.5.4 进程调度时机 182 4.6 进程切换过程分析 183 4.6.1 选取合适进程 183 4.6.2 完成上下文切换 184 4.7 空闲进程的初始化 187 4.7.1 空闲进程的内核态栈 187 4.7.2 空闲进程...

    Linux2.6内核标准教程(共计8--第7个)

    4.5.3 时间片分配 181 4.5.4 进程调度时机 182 4.6 进程切换过程分析 183 4.6.1 选取合适进程 183 4.6.2 完成上下文切换 184 4.7 空闲进程的初始化 187 4.7.1 空闲进程的内核态栈 187 4.7.2 空闲进程...

    Linux2.6内核标准教程(共计8--第2个)

    4.5.3 时间片分配 181 4.5.4 进程调度时机 182 4.6 进程切换过程分析 183 4.6.1 选取合适进程 183 4.6.2 完成上下文切换 184 4.7 空闲进程的初始化 187 4.7.1 空闲进程的内核态栈 187 4.7.2 空闲进程...

    进程调度基于时间片的.

    编程实现四种调度算法: (1) 先来先服务算法 (2) 短作业优先算法 (3) 优先权算法 (4) 基于时间片的多级反馈队列算法 ⒉ 基本要求 (1) 通过若干个实例实现各种算法的优劣性对比; (2) 结果要求可视化展示 ⒊ 实现...

    论文研究-一种实时性O(1)调度改进算法.pdf

    保留了I/O队列以缩短I/O请求的响应时间,同时采用动态计算优先级和时间片的方法来使通用进程调度达到最优。最后,通过仿真实验的结果比较,证明了RMOSA算法相对于Linux 2.6.11O(1)调度算法的优越性。

    多CPU控制系统时间片轮转调度的一种算法.pdf

    多CPU控制系统时间片轮转调度的一种算法.pdf

    Linux2.6内核标准教程(共计8--第4个)

    4.5.3 时间片分配 181 4.5.4 进程调度时机 182 4.6 进程切换过程分析 183 4.6.1 选取合适进程 183 4.6.2 完成上下文切换 184 4.7 空闲进程的初始化 187 4.7.1 空闲进程的内核态栈 187 4.7.2 空闲进程...

    Linux2.6内核标准教程(共计8--第5个)

    4.5.3 时间片分配 181 4.5.4 进程调度时机 182 4.6 进程切换过程分析 183 4.6.1 选取合适进程 183 4.6.2 完成上下文切换 184 4.7 空闲进程的初始化 187 4.7.1 空闲进程的内核态栈 187 4.7.2 空闲进程...

    处理机调度.xmind

    时间片用完 有更紧急的事情处理(I/O中断) 有更高优先级的进程进入就绪队列 什么时候不能进行进程调度 处理中断的过程中 进程在操作系统内核程序临界区中 原子操作过程中 切换与过程 ...

    Linux内核中的进程

    在2.6.23内核版本中用完全公平调度算法(CFS)代替了O(1)调度算法。  进程可以被分为I/O消耗型和处理器消耗型。I/O消耗型指进程的大部分时间用来提交I/O请求或是等待I/O请求。处理器消耗型指进程把事件大多数用在...

    操作系统进程调度算法

    进程是操作系统最重要的概念之一,进程调度是操作系统内核的重要功能,本实验要求用C语言编写一个进程调度模拟程序,使用优先级或时间片轮转法实现进程调度。本实验可加深对进程调度算法的理解。

    嵌入式实时操作系统μCOS-3.pdf

    μC/OS-III允许利用这类高端CPU的特殊硬件指令来实现高效的任务调度算法,而无须使用μC/OS-II的软件任务调度算法,而且μC/OS-II支持时间片轮转调度算法。从核心任务调度算法的改变来看,μC/OS-III已经是一个...

    进程调度基本框架

    进程是操作系统最重要的概念之一,进程调度是操作系统内核的重要功能,本实验要求用C语言编写一个进程调度模拟程序,使用优先级或时间片轮转法实现进程调度 2)按照实验题目要求独立正确地完成实验内容(编写、调试...

    清华大学Linux操作系统原理与应用

    3.4.2 时间片 50 3.4.3 Linux进程调度时机 50 3.4.4 进程调度的依据 51 3.4.5 调度函数schedule()的实现 52 3.5 进程的创建 54 3.5.1 创建进程 55 3.5.2 线程及其创建 56 3.6 与进程相关的系统调用及其应用 58 3.6.1...

    嵌入式系统/ARM技术中的嵌入式μC/OS-Ⅱ任务调度算法的改进

    针对分时任务,新增加时间片调度算法,给出调度算法的实现方法,同时增加任务创建和销毁的接口;降低基于μC/OS-1I操作系统的嵌入式产品开发难度和设计成本,有利于该操作系统的应用推广。  目前,操作系统内核的...

    操作系统各部分内容详细思维导图.zip

     先来先服务调度算法,短作业(短进程、短线程)优先调度算法,时间片轮转  调度算法,优先级调度算法,高响应比优先调度算法,多级反馈队列调度算法。  (三)同步与互斥  1.进程同步的基本概念  2.实现临界区...

Global site tag (gtag.js) - Google Analytics