(笔记)Linux内核学习(十一)之I/O层和I/O调度机制
一 块I/O基本概念
字符设备:按照字符流的方式被有序访问的设备。如串口、键盘等。
块设备:系统中不能随机(不需要按顺序)访问固定大小的数据片(chunk 块)的设备。
如:硬盘、软盘、CD-ROM驱动器、闪存等。都是通过以安装文件系统的方式使用。
块设备的组成:
扇区:是块设备中最小的可寻址单元(常见大小512字节);是块设备的基本寻址和操作单元。
块:是文件系统最小逻辑可寻址单元,文件系统的抽象,只能通过块访问文件系统。通常包含多个扇区。
当一个块被调入内存时(读入后或等待写出时),它要存储在一个缓冲区中;每个缓冲区与一个块对应,
缓冲区相当于是磁盘块在内存中的表示;块大小不超过一个页面,一个页可以容纳一个或多个内存中的块。
缓冲区:是内核操作块设备的逻辑单元,每个缓冲区需要一个描述符来表示块的控相关制信息。
数据结构:缓冲区头 buffer_head,内核操作I/O块基本容器是:bio。操作内核中所有的缓冲区对应的I/O块。
请求队列:块设备将他们挂起的块I/O请求保存在请求队列中。
二 I/O调度机制
简单的以内核产生I/O请求的次序直接将请求发向块设备,造成性能将难以接受。因为磁盘寻址是整个计算机中
最慢的操作之一,每一次寻址定位硬盘磁头到特定块上某个位置需要花费不少时间;要提高I/O操作性能,尽量缩短磁盘寻址时间。
在提交请求到块设备前,内核需要对请求进行处理:先执行合并与排序的预操作——I/O调度机制子系统,负责I/O请求的提交。
I/O调度程序管理块设备的请求队列,决定队列中的请求排列顺序,何时派发请求到设备。以减少磁盘寻址时间,提高全局吞吐量。
其实现的方法是合并与排序:
合并:将两个或多个请求结合成一个新的请求,比如访问磁盘扇区相邻时,合并为一个对单个和多个相邻磁盘扇区操作的新请求。
合并后仅需要一次请求一条寻址命令。
排序:没有相邻操作扇区请求时,但可能是比较接近的;将整个请求队列按扇区增长方向有序排列,操作时保持磁头以直线一个
方向移动,缩短请求磁盘寻址时间。
三 调度程序实现
1 Linus Elevator
当一个请求加入到队列时:
如果队列已存在一个对相邻磁盘扇区操作的请求,将新请求和这个已存在的请求合并成一个请求。
如果队列中存在一个驻留时间过长的请求,将新请求插入到队列尾部,防止请求发生饥饿。
如果队列中以扇区方向为序存在合适插入位置,将新请求插入到该位置,与被访问磁盘物理位置为序排列。
如果队列不存在合适位置插入,将请求插入到队列尾部。
2 最终期限I/O调度程序
Linus Elevator调度程序存在使请求发生饥饿的情况:
l 对某个磁盘区域繁重操作,使得磁盘其他位置上的操作请求得不到运行;
l 同一位置顺序上的请求流可以造成较远位置请求得不到运行;
l 写操作和提交应用程序是异步执行,读操作和提交应用程序是同步执行会阻塞,读操作响应时间影响性能。
要在提高全局吞吐量和使请求得到公平处理之间进行平衡。
最终期限I/O调度程序中:每个请求都有一个超时时间,读请求默认500毫秒,写请求5秒。
提交请求时:
一个请求递交给排序队列,按照合并和排序插入队列;
将读请求按次序插入到读FIFO队列中;
将写请求按次序插入到写FIFO队列中;
派发请求时:
通常从排序队列中取队首请求加入到派发队列中;
如果写FIFO队列首或读FIFO队列首请求超时,调度程序从FIFO队列中提取队首请求加入到派发队列中。
如下图所示:
此方式能尽量保证:
请求超时前得到执行,防止请求发生饥饿;
读请求超时时间比写请求短很多,保证写请求不会因为堵塞读请求而使读请求发生饥饿。
3 预测I/O调度程序
最终期限调度程序降低请求发生饥饿的概率,同时降低了系统吞吐量。预测I/O调度程序的目标就是在保持
良好读响应同时提供良好的全局吞吐量。
预测I/O调度程序与最终期限调度程序不同之处:请求提交后并不直接放回处理其他请求,而是会空闲片刻(6毫秒),
使应用程序有提交其他请求的机会——任何对相邻磁盘位置的操作请求都会立刻得到处理,等待结束后,预测I/O调度程序
重新返回原来的位置,继续执行以前的剩下请求。
预测I/O调度程序所能带来的优势取决于能否正确预测应用程序和文件系统的行为,需要启发和统计工作,预测准确能够
减少寻址开销,提高系统响应,提高吞吐量。
还有其他调度程序:完全公正的排队I/O调度程序(每个进程独立I/O请求队列)和空操作I/O调度程序(相邻合并)
要在提高全局吞吐量和使请求得到公平处理之间进行平衡。
系统调度程序再启动时可以进行配置。
(笔记)Linux内核学习(十一)之I/O层和I/O调度机制的更多相关文章
- (笔记)Linux内核学习(九)之内核内存管理方式
一 页 内核把物理页作为内存管理的基本单位:内存管理单元(MMU)把虚拟地址转换为物理 地址,通常以页为单位进行处理.MMU以页大小为单位来管理系统中的也表. 32位系统:页大小4KB 64位系统:页 ...
- (笔记)Linux内核学习(四)之系统调用
一 用户空间和内核空间 Linux内核将这4G字节虚拟地址空间的空间分为两部分: l 将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用,称为“内核空间”. l ...
- (笔记)Linux内核学习(一)之内核介绍
内核与操作系统: 内核是操作系统的核心部分,包含了系统运行的核心过程,决定系统的性能,操作系统启动内核被装入到RAM中: 操作系统与底层硬件设备交互和为运行应用程序提供执行环境. Linux内核与微内 ...
- (笔记)Linux内核学习(二)之进程
一 进程与线程 进程就是处于执行期的程序,包含了独立地址空间,多个执行线程等资源. 线程是进程中活动的对象,每个线程都拥有独立的程序计数器.进程栈和一组进程寄存器. 内核调度的对象是线程而不是进程.对 ...
- (笔记)Linux内核学习(十)之虚拟文件系统概念
虚拟文件系统 虚拟文件系统:内核子系统VFS,VFS是内核中文件系统的抽象层,为用户空间提供文件系统相关接口: 通过虚拟文件系统,程序可以利用标准Linux文件系统调用在不同的文件系统中进行交互和操作 ...
- (笔记)Linux内核学习(三)之进程调度
进程调度: 在可运行态进程之间分配有限处理器时间资源的内核子系统. 一 调度策略 1 进程类型 I/O消耗型进程:大部分时间用来提交I/O请求或是等待I/O请求,经常处于可运行状态,但运行时间短,等待 ...
- (笔记)Linux内核学习(八)之定时器和时间管理
一 内核中的时间观念 内核在硬件的帮助下计算和管理时间.硬件为内核提供一个系统定时器用以计算流逝的时间.系 统定时器以某种频率自行触发,产生时钟中断,进入内核时钟中断处理程序中进行处理. 墙上时间和系 ...
- (笔记)Linux内核学习(六)之并发和同步概念
一 临界区和竞争条件 临界区:访问和操作共享数据的代码段. 竞争条件:多个执行线程处于同一个临界区中. 处于竞争条件:造成访问的数据或者资源不一致状态: 对资源i的访问:ProcessA和B访问后得到 ...
- (笔记)Linux内核学习(七)之内核同步机制和实现方式
一 原子操作 指令以原子的方式执行——执行过程不被打断. 1 原子整数操作 原子操作函数接收的操作数类型——atomic_t //定义 atomic_t v;//初始化 atomic_t u = AT ...
随机推荐
- Visual Stuido 在文件中查找不显示结果
出现好几次了.解决方法如下: 注册表找到 HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{73B7DC00-F498-4ABD-AB79-D07AFD52F395}\InPr ...
- LintCode 整数排序
题目:给一组整数,按照升序排序,使用选择排序,冒泡排序,插入排序或者任何 O(n2) 的排序算法. 1.冒泡:从头开始,比较相邻的两个元素,大的放在后面.一轮结束之后,最大的数沉底,不参与下一轮比较. ...
- AndroidStudio Lod.d在LogCat中不输出
今天Log.d无论怎样都没有输出. 要在手机开发者选项那开启权限,莫名其妙,之前一直都没事的,具体操作参考:http://jingyan.baidu.com/article/84b4f56597e7b ...
- SQL Server 处理树结构数据的一个示例
没多少技术含量,在简单的系统里应用问题不大: 解决的问题是: 1.树结构数据的表设计: 2.对任意一个节点,找到他所有的上级节点 3.对任意一个节点,找到他所有的下级节点 这里的部分SQL是同事给的, ...
- nginx lua整合安装
安装lua JIT 下载 wget http://luajit.org/download/LuaJIT-2.0.4.tar.gz 解压: tar zxvf LuaJIT-2.0.4.tar.gz 进入 ...
- 跟我一起学WCF(12)——WCF中Rest服务入门
一.引言 要将Rest与.NET Framework 3.0配合使用,还需要构建基础架构的一些部件.在.NET Framework 3.5中,WCF在System.ServiceModel.Web组件 ...
- solr与.net系列课程(六)solr定时增量索引与安全
solr与.net系列课程(六)solr定时增量索引与安全 solr增量索引的方式,就是一个Http请求,但是这样的请求显然不能满足要求,我们需要的是一个自动的增量索引,solr官方提供了一个定时器 ...
- Fragment之间的通信
在本节中,你会学到 1.定义接口 2.实现接口 3.将消息传递给fragment 为了重用Fragment UI 组件,在设计中你应该通过定义每一个fragemnt自己的layout和行为,让frag ...
- mongo(三)基本操作
mongo(三)基本操作 本文来自mongodb官方文档的部分翻译以及自己的理解. CRUD:增加(Create).读取(Retrieve)(重新得到数据).更新(Update)和删除(Delet ...
- celery与mangodb搭配应用
写作背景介绍 在celery简单应用中已经介绍了如何去配置一个celery应用,也知道怎么分离任务逻辑代码与客户端代码了.我们现在的任务是怎么把计算结果保存到数据库中,这种数据持久化是非常重要的.你一 ...