标签:搜索 寻址 用户 osc tor 通用 步骤 pat 模型
Linux内核实现I/O主要在三个内核子系统:虚拟文件系统(VFS),页缓存,和页回写。I/O调度器和I/O性能
磁盘寻址要理解I/O调度器的工作机制,需要先了解一些背景知识。硬盘基于用柱面(cylinders),磁头(heads),和扇区(section)几何寻址方式来获取数据,这种方式也被成为CHS寻址。每个硬盘都是由多个盘片组成,每个盘片包括一个磁盘、一个主轴和一个读写头。
I/O调度器实现两个基本操作:
1,合并(merging)操作是将两个或多个相邻的I/O请求的过程合并为一个。考虑两次请求,一次读取5号块,另一次读取6和7上的数据。这些请求被合并为一个对块5到7的操作。总的I/O吞吐量可能一样,但是I/O的次数减少了一半。
2,排序(sorting)是选取两个操作中相对更重要的一个,并按块号递增的顺序重新安排等待的I/O请求。比如说,I/O操作要求访问块52,109,和7,I/O调度这三个请求以7,52,109的顺序进行排序.如果一个请求现在要访问81,它将被插入到访问52和109的中间。I/O调度器然后按他们在队列中的顺序一次调度:7,然后52,然后81,最后109。
每次读请求必须返回最新的数据。因此,当请求的数据不在页缓存中时,读请求在数据从磁盘读出前一直会阻塞——这可能是一个相当漫长的操作。我们将这种性能损失称为读延迟(read latency)。一个典型的程序可能在短时期有几个I/O请求。因为每个请求都分别进行同步,稍后的请求将依赖于前面请求。当写操作需要在队列中插入多个块时,队列尾部的块读延迟会变得非常严重。这种现象就是著名的writes-starving-reads问题。
I/O 调度器使用一种机制避免”饿死”的发生。最简单的方法就是像2.4内核那样采用Linux电梯调度法。在该方法中,如果队列中有一定数量的旧的请求,则停止插入新的请求。这样整体上可以做到平等对待每个请求,但在读的时候,却增加了读延迟(read latency)。2.6内核丢弃了Linus电梯调度算法,转而使用了几种新的调度器算法。
1,Deadline I/O调度器,是为了解决2.4调度程序及传统的电梯调度算法的问题。Linus电梯算法维护了一个经过排序的I/O等待列表。队列首的I/O请求是下一个被调度的。DeadlineI/O调度器保留了这个队列,为了进一步改进了原来的调度器,增加了两个新的队列:读FIFO队列和写FIFO队列。FIFO 队列中的每个请求都设置一个过期时间。读 FIFO队列的过期时间设置为500毫秒,写队列则为5 秒。
2,Anticipatory I/O调度器,Deadline I/O调度器表现很好,但是并不完美。当面对众多独立的读请求时,问题依然会出现-每个读请求在前一个请求返回后才会执行,当应用程序得到数据,准备运行并提交了下一个读请求时, I/O 调度程序已经去处理其他的请求了。这样导致了每次搜索时都要进行不必要的寻道操作:查找数据,读数据,返回。
AnticipatoryI/O调度器在Deadline I/O调度器中增加了预测机制,当一个读操作被提交,anticipatory I/O 调度器在它的终止期限前调度它。不同于Deadline I/O 调度器的是, anticipatory I/O 调度器会等待6毫秒。如果应用程序在6 毫秒内对硬盘同一部分发出另一次读请求,读请求立刻被响应, anticipatory I/O 调度器继续等待。
3,CFQ I/O调度器,尽管在方法上有所区别,但Complete Fair Queuing(CFQ)I/O调度器和上述调度程序的目标是相同的。使用CFQ时,每个进程都有自己的队列,每个队列分配一个时间片。I/O调度程序使用轮转方式访问并处理队列中的请求,直到队列的时间片耗尽或所有的请求都被处理完。后一种情况,CFQ I/O调度器将会空转一段时间(默认10毫秒),等待当前队列中新的请求。如果预测成功,I/O调度器避免了查找操作。如果预测无效,调度程序转而处理下一个进程的队列。
4,Noop I/O调度器,NoopI/O调度程序是目前最简单的调度器。无论什么情况,它都不进行排序操作,只是简单的合并。它一般用在不需要对请求排队的特殊设备上。
调度器默认的I/O调度器可以在启动时可以通过内核参数iosched来指定。有效的选项有as,cfq,deadline,和noop。也可以在运行时针对每个块设备进行选择,可以通过修改/sys/block/device/queue/scheduler来完成。读这个文件可以知道当前的I/O调度器是什么,把上述有效选项写入这个文件可以更改I/O调度程序。例如,要设置设备hda的I/O调度程序为CFQ , 可以使用如下方式:
#echo cfq >/sys/block/hda/queue/scheduler
因为磁盘I/O相比系统其它部分很慢,同时I/O系统又是现代计算机很重要的一个部分,因此使I/O性能达到最优是非常重要的。减少I/O操作的次数(通过将很多小的操作聚集为一些大的操作),实现块对齐的I/O,或者使用用户空间缓冲,利用高级I/O的优点,如向量I/O,定位I/O和异步I/O,都是系统编程过程中需要经常考虑的重要步骤。为了使I/O请求能以有利于寻址操作的顺序提交,用户空间程序可以做不同的处理。它们可按照以下方式进行排序:
1,完整路径:在大部分文件系统采用的布局算法中,每个目录里的文件, 倾向于在磁盘上相邻分布。
2,inode编号:使用inode排序比路径排序更有效 ,通常情况下,inode的顺序意味着物理块的顺序。
3,文件的物理块:通过文件逻辑块获得物理块,然后再排序。。第一步,确定文件中块的数量。这可以通过stat()调用来完成。其次,对每个逻辑块,我们用ioctl()调用获得与它相关的物理块。
标签:搜索 寻址 用户 osc tor 通用 步骤 pat 模型
原文地址:http://blog.51cto.com/13376824/2060952