一、I/O管理概述
1.1 计算机I/O系统结构
1.2 I/O管理示意图
1.3 I/O的特点
-
I/O
性能经常称为系统性能的瓶颈 - 操作系统庞大复杂的原因之一:资源多、杂,并发,均来自
I/O
- 速度差异很大
- 应用
- 控制接口的复杂性
- 传送单位
- 数据表示
-
错误条件
- 与其他功能联系密切,特别是文件系统。
1.4 设备的分类:按数据组织分
- 块设备
以数据块为单位存储、输出信息。传输速率较高、可寻址(随机读写) - 字设备
以字符为单位存储、传输信息。传输速率低、不可寻址。
1.5 设备的分类:从资源分配角度
- 独占设备
在一段时间内只能有一个进程使用的设备,一般为低速I/O
设备(如打印机,磁带等) - 共享设备
在一段时间内可由多个进程共同使用的设备,多个进程以交叉的方式来使用设备,其资源利用率高(如硬盘) - 虚设备
在一类设备上模拟另一类设备,常用共享设备模拟独占设备,用高速设备模拟低速设备,被模拟的设备称为虚设备。其目的就是将慢速的独占设备改造成多个用户可共享的设备,提高设备的利用率。如SPOOLing
技术-
SPOOLing技术
当系统中引入多道程序技术后,完全可以利用其中一道程序,来模拟脱机输入时的外围控制机功能,把低速I/O设备上的数据传送到高速磁盘上;再用另一道程序来模拟脱机输出时的外围控制机功能,把数据从磁盘传送到低速设备上。这样,便可以在主机的直接控制下,实现脱机输入、输出功能。此时的外围操作与CPU对数据的处理同时进行,我们把这种在联机情况下实现的同时外围操作称为,或称为假脱机操作
SPOOLING系统主要有以下四部分:(1)输入井和输出井 (2)输入进程和输出进程 (3)输入缓冲区与输出缓冲区 (4)井管理程序
-
1.6 I/O管理的目标和任务
-
1、按照用户的请求,控制设别的各种操作,完成
I/O
设备与内存之间的数据交换,最终完成用户的I/O
请求- 设备分配与回收
(1)记录设备的状态
(2)根据用户的请求和设备的类型,采用一定的分配算法,选择一条数据通路 - 执行设备驱动程序,实现真正的
I/O
操作 - 设备中断处理:处理外部设备的中断
- 缓冲区管理:管理
I/O
缓冲区
- 设备分配与回收
-
2、建立方便、统一的独立于设备的接口
- 方便性:向用户提供使用外部设备的方便接口,使用户编程时不考虑设备的复杂物理特性
- 统一性:对不同的设备采用统一的操作方式,即在用户程序中使用的是逻辑设备
(1)逻辑设备与物理设备
(2)屏蔽硬件细节(设备的物理特性、错误处理、不同I/O
过程的差异性)
-
3、充分利用各种技术(通道,中断,缓冲,异步
I/O
等)提高CPU
与设备、设备与设备之间的并行工作能力,充分利用资源,提高资源利用率。
(1)并行性
(2)均衡性(使设备充分忙碌)
- 4、保护
设备传送或管理的数据应该是安全的、不被破坏的、保密的
二、I/O硬件组成
2.1 I/O设备组成
-
I/O
设备一般由机械和电子两部分组成
(1)机械部分是设备本身(物理装置)
(2)电子部分又称设备控制器(或适配器)- 端口地址译码
- 按照主机与设备之间约定的格式和过程接受计算机发来的数据和控制信号 或 向主机发送数据和状态信号
- 将计算机的数字信号转换成机械部分能识别的模拟信号,或反之
- 实现设别内部硬件缓冲、数据加工等提高性能或增强功能
2.2 设备接口:控制器的作用
- 操作系统将命令写入控制器的接口寄存器(或接口缓冲区)中,以实现输入/输出,并从接口寄存器读取状态信息或结果信息
- 当控制器接受一条命令后,可独立于
CPU
完成指定操作,CPU
可以另外执行其他计算;命令完成时,控制器产生一个中断,CPU
响应中断,控制器转给操作系统;通过读控制器寄存器中的信息,获得操作结果和设备状态 - 控制器与设备之间的接口常常是一个低级接口
- 控制器的任务:把串行的位流转换为字节块,并进行必要的错误修正。首先,控制器按位进行组装,然后存入控制器内部的缓冲区中形成以字节为单位的块;在对块验证检查和并证明无错误时,再将它复制到内存中
2.3 I/O端口地址
-
I/O
端口地址:接口电路中每个寄存器具有的、唯一的地址,是个整数 - 所有
I/O
端口地址形成I/O
端口空间(受到保护)
说明:左边是有一块内存和一个I/O
端口地址空间;中间就是一块内存,其中有一部分用作I/O
端口地址空间;而右边是一种混合模式,内存中有一部分用于I/O
端口,在外部还有一个独立的I/O
端口地址空间。
2.4 I/O独立编址
- 分配给系哦他能够中所有端口的地址空间是完全独立的,与内存地址空间无关
- 使用专门的
I/O
指令对端口进行操作 - 优点
- 外设不占用内存的地址空间
- 编程时,易于区分是对内存操作还是对
I/O
操作
- 缺点:
I/O
端口操作的指令类型少,操作不灵活 - 例子:
8086/8088
,分配给I/O
端口的地址空间为64k
,0000H~0FFFFH
,只能用in
和out
指令进行读写操作
2.5 内存映像编址
- 分配给系统中所有端口的地址空间与内存的地址空间统一编址
- 把
I/O
端口看作一个存储单元,对I/O
的读写操作等同于对内存的操作 - 优点
- 凡是可对内存操作的指令都可对
I/O
端口操作 - 不需要专门的
I/O
指令 -
I/O
端口可占有较大的地址空间
- 凡是可对内存操作的指令都可对
- 缺点:占用内存空间
2.6 内存映射I/O的优点
- 不需要特殊的保护机制来阻止用户进程执行
I/O
操作
操作系统必须要做的事情:避免把包含控制寄存器的那部分地址空间放入任何用户的虚拟地址空间之中 - 可以引入内存的每一条指令也可以引用控制寄存器
例如,如果指令TEST
可以测试一个内存字是否为零,那么它也可以用来测试一个控制寄存器是否为零。
2.7 内存映射I/O的缺点
- 对一个设备控制寄存器不能进行高速缓存
- 考虑以下汇编代码循环,第一次引用
PORT_4
将导致它被高速缓存,随后的引用将只从高速缓存中取值并且不会再查询设备,之后当设备最终变为就绪时,软件将没有办法发现这一点,结果循环将永远进行下去
- 为避免这一情形,硬件必须针对每个页面具备选择性禁用高速缓存的能力,操作系统必须管理选择性高速缓存,所以这一特性为硬件和操作系统增添了额外的复杂性。
三、I/O控制方式(重点)
3.1 I/O控制方式
- 可编程
I/O
(轮询/查询)
由CPU
代表进程给I/O
模块发I/O
命令,进程进入忙等待,直到操作完成才继续执行 - 中断驱动
I/O
为了减少设备驱动程序不断地询问控制器状态寄存器的开销。I/O
操作结束后,由设备控制器主动通知设备驱动程序 -
DMA
(直接存储器访问)
主要差别在于:
中央处理器和外围设备并行工作的方式不同,
并行工作的程度不同。
3.2 轮询方式的工作过程
使用轮询的可编程I/O方式称为忙—等待方式。
当处理机向控制器发出一条I/O指令启动输入设备时
- 状态寄存器中的busy置为1
b. 处理机循环测试busy标志,直至busy=0。
- 当busy=1时,表示输入机尚未输完一个字
c. 处理机将数据寄存器中的数据取出,送入内存指定单元中,这样便完成了一个字(符)的I/O。
对CPU的极大浪费
- CPU的高速性和I/O设备的低速性
致使CPU绝大部分时间都处于等待I/O设备完成数据I/O的循环测试中
在CPU中无中断机构
- 使I/O设备无法向CPU报告它已完成了一个字符的输入操作
- CPU要不断地测试I/O设备的状态
说明:应用程序发出了一个读数据的请求,设备驱动程序检查设备状态,没问题则给设备发出控制命令,然后不断测试设备是否完成了这次过程,完成之后将数据发送给应用程序。
3.3 中断驱动的工作过程
- 引入中断机构, 实现了一定程度的并行操作
- 无需CPU干预,使CPU与I/O设备并行工作
- 仅当输完一个数据时,才需CPU花费极短的时间去做些中断处理
- 提高了整个系统的资源利用率及吞吐量
说明:首先还是应用程序提出请求,设备驱动程序检查状态,如果没问题则发出控制命令,之后将设备状态记录在设备状态表中,此时
CPU
可以做别的事情,当设备完成之后会给CPU
发出信号,转入中断处理程序,中断处理程序将结果交给设备处理程序,而设备处理程序将数据发送给应用程序。
3.4 直接存储访问(DMA)方式的工作过程
中断驱动I/O方式的CPU是以字(节)为单位进行干预
-
特点
- 数据传输的基本单位是数据块
- 整块数据的传送在控制器控制下完成
- 所传数据直接从设备送入内存,或相反
- 仅在传送数据块的开始和结束时,需CPU干预
-
相比中断驱动方式
提高了CPU与I/O设备的并行操作程度
DMA方式
DMA控制器需如下四类寄存器:
(1)命令/状态寄存器(CR)。
(2)内存地址寄存器MAR
(3)数据寄存器DR
(4)数据计数器DC
3.5 I/O通道控制方式
I/O通道方式是DMA方式的发展,是一种I/O专用处理器
它把对一个数据块的读(写)为单位的干预减少为对一组数据块的读(写)及有关的控制和管理为单位的干预
实现CPU、通道和I/O设备三者的并行操作
更有效地提高整个系统的资源利用率。
- 当CPU要完成一组相关操作及控制时,只需向I/O通道发送一条I/O指令。
通道程序
通道程序由一系列通道指令构成。
通道指令中都包含下列诸信息
通道程序结束位 P=1表示结束
记录结束标志
- R=0,表示本指令与下一指令处理同一个记录
- R=1,表示处理某记录的最后一条指令
3.6 I/O部件的演化
四、I/O软件组成
4.1 I/O软件设计
分层设计思想:
- 把
I/O
软件组织成多个层次 - 每一层都执行操作系统所需要的功能的一个相关子集,它依赖于更低一层所执行的更原始的功能,从而可以隐藏这些功能的细节;同时,它又给高一层提供服务
- 较低层考虑硬件的特性,并向较高层软件提供接口
-
较高层不依赖于硬件,并向用户提供一个友好的、清晰的、简单的、功能更强的接口
4.2 I/O软件层次(重点)
- 用户进程层执行输入输出系统调用,对
I/O
数据进行格式化,为假脱机输入输出做准备 - 独立于设备的软件实现设备的命名、设备的保护、成块处理、缓冲技术和设备分配
- 设备驱动程序设置设备寄存器、检查设备的执行状态
- 中断处理程序负责
I/O
完成时,唤醒设备驱动程序进程,进行中断处理 - 硬件层实现物理
I/O
的操作。
设备独立性(无关性)
即用户编写的程序可以访问任意I/O
设备,无需事先指定设备。这样做的好处是设备分配时的灵活性,易于实现I/O
重定向。
- 从用户角度:用户在编制程序时,使用逻辑设备名,由系统实现从逻辑设备到物理设备的转换,并实施
I/O
操作 - 从系统角度:设计并实现
I/O
软件时,除了直接与设备打交道的底层软件之外,其他部分的软件不依赖于硬件
五、I/O相关技术
我们知道,缓冲技术是操作系统中最早引入的技术,最初是为了解决cpu
与I/O
设备之间速度不匹配的问题。
而今天,凡是数据到达和离去的速度不匹配的地方均可采用缓冲技术,提高cpu
与I/O
设备的并行性,减少I/O
设备对cpu
的中断请求次数,放宽cpu
对中断响应时间的要求。
5.1 缓冲技术的实现
- 缓冲区分类
硬缓冲:由硬件寄存器实现
软缓冲:在内存中开辟一个空间,用作缓冲区。 - 缓冲区的管理
单缓冲:即一个缓冲区
双缓冲:即两个缓冲区
循环缓冲
缓冲池:统一管理多个缓冲区,采用有界缓冲区的生产者/消费者模型对缓冲池中的缓冲区进行循环调用。
5.2 UNIX SYSTEM V缓冲技术
这个版本的UNIX
系统采用缓冲技术可以达到下面目标:
- 采用缓冲技术,可平滑和加快信息在内存和磁盘之间的传输
- 缓冲区结合提前写和延迟写技术对具有重复性及阵发性
I/O
进程、提高I/O
速度很有帮助。 - 可以充分利用之前从磁盘读入、虽已传入用户区但仍在缓冲区的数据(尽可能减少磁盘
I/O
的次数,提高系统运行的速度)
5.2.1 实现
- 这里缓冲池:
200
个缓冲区(512
字节和1024
字节) - 每个缓冲区由两部分组成:缓冲控制块或缓冲首部+缓冲数据区。系统通过缓冲控制块来实现对缓冲区的管理。
- 空闲缓冲队列(
av
链)
队列头部为bfreelist
- 设备缓冲队列(
b
链)
链接所有分配给各类设备使用的缓冲区,按照散列方式组织。
5.2.2 说明
- 逻辑设备号和盘块号分别标志出文件系统和数据所在的盘块号,是缓冲区的唯一标志。
- 状态标识缓冲区的当前状态:忙/闲、上锁/开锁、是否延迟写、数据有效性等
- 两组指针(
av
和b
)用于对缓冲池的分配管理
5.2.3 分析各类场景
每个缓冲区同时在av
链和b
链:
- 开始:在空闲
av
链(缓冲区未被使用时) - 开始
I/O
请求:在设备I/O
请求队列和设备b链 -
I/O
完成:在空闲av
链和设备b链
5.2.4 缓冲区的使用过程
-
当进程想从指定的盘块读取数据时,系统根据盘块号从设备
b
链(散列队列)中查找,如找到缓冲区,则将该缓冲区状态标记为“忙”,并从空闲av
链队列中取下,并完成从缓冲区到内存用户区的数据传送。 -
如果在设备
b
链中未找到时,则从空闲av
链队列首部摘取一个缓冲区,插入设备IO
请求队列,并从原设备b
链中取下,插入由读入信息盘块号确定的新的设备b
链中。 -
当数据从磁盘块读入到缓冲区后,缓冲区从设备
IO
请求队列取下;当系统完成从缓冲区到内存用户区的数据传送后,要把缓冲区释放,链入空闲av
链队尾。 -
当数据从磁盘块读入到缓冲区,并传送到内存用户区后,该缓冲区一直保留在原设备
b
链中,即它的数据一直有效。若又要使用它,则从空闲av
链中取下,使用完后插入到空闲av
链队尾。若一直未使用,则该缓冲区从空闲av
链队尾慢慢升到队首,最后被重新分配,旧的盘块数据才被置换。 -
系统对缓冲区的分配是采用近似
LRU
算法。
六、I/O设备的管理
6.1 设备管理有关的数据结构
-
系统为每一个I/O设备都配置了一张用于记录本设备情况的设备控制表(Device Control Table,DCT)。
设备控制表 -
系统为每一个控制器都配置了一张记录本控制器情况的控制器控制表(COntroler Control Table,COCT)。
控制器控制表 -
每个通道都有一张通道控制表(CHannel Control Table,CHCT)。
该表只有在通道控制方式的系统中存在。
通道控制表 - 系统建立一张系统设备表(SDT)
记录配置在系统中的所有物理设备的情况。
每台物理设备占用一栏,包括-
设备类型、台数、设备号、设备控制表指针等
系统设备表
-
6.2 独占设备的分配
-
在申请设备时,如果设备空闲,就将其独占,不再允许其他区进程申请使用,一直等到该设备被释放,才允许被其他进程申请使用。考虑到效率问题,并避免由于不合理的分配策略造成死锁
- 静态分配
在进程运行前,完成设备分配;运行结束时,收回设备。缺点就是设备利用率低。 - 动态分配
在进程运行过程中,当用户提出设备要求时,进行分配,一旦停止使用立即回收。优点就是效率高。缺点就是分配策略不好时,会产生死锁。
- 静态分配
-
分时式共享设备的分配
- 所谓分时式共享就是以一次
IO
为单位分时使用设备,不同进程的IO
操作请求以排队方式分时地占用设备进行IO
- 由于同时有多个进程同时访问,且访问频繁,就会影响整个设备使用效率,影响系统效率。因此,要考虑多个访问请求到达时服务的顺序,使平均服务时间越短越好。
- 所谓分时式共享就是以一次
6.3 设备驱动程序
-
与设备密切相关的代码放在设备驱动程序中,每个设备驱动程序处理一种设备类型
-
一般地,设备驱动程序的任务是接收来自与设备无关的上层软件的抽象请求,并执行这个请求。
-
每一个控制器都设有一个或多个设备寄存器,用来存放向设备发送的命令和参数。设备驱动程序负责释放这些命令,并监督它们正确执行。
-
在设备驱动程序的进程释放一条或多条命令后,系统有两种处理方式,多数情况下,执行设备驱动程序的进程必须等待命令完成,这样,在命令开始执行后,它阻塞自己,直到中断处理时将它解除阻塞为止;而在其它情况下,命令执行不必延迟就 很快完成。
-
设备驱动程序与外界的接口
- 与操作系统的接口
为实现设备无关性,设备作为特殊文件传处理。用户的IO
请求、对命令的合法性检查以及参数处理在文件系统中完成。在需要各种设备执行具体操作时,通过相应的数据结构转入不同的设备驱动程序 - 与系统引导的接口(初始化,包括分配数据结构建立设备的请求队列)
- 与设备的接口
- 与操作系统的接口
-
设备驱动程序接口函数
- 驱动程序初始化函数(如向操作系统登记该驱动程序的接口函数,该初始化函数在系统启动时或驱动程序安装入内核执行)
- 驱动程序卸载函数
- 申请设备函数
- 释放设备函数
-
IO
操作函数
对独占设备,包含启动IO
的指令;对共享设备,将IO
请求形成一个请求包,排到设备请求队列,如果请求队列空,则直接启动设备 - 中断处理函数
对IO
完成做善后处理,一般是唤醒等待刚完成IO
请求的阻塞进程,时期能进一步做后续工作;如果存在IO
请求队列,则启动下一个IO
请求。
6.4 一种典型的实现方案:I/O进程
-
IO
进程:专门处理系统中的IO
请求和IO
中断工作 -
IO
请求的进入- 用户程序:调用
send
将IO
请求发送给IO
进程;调用block
将自己阻塞,直到IO
任务完成后被唤醒 - 系统:利用
wakeup
唤醒IO
进程,完成用户所要求的IO
处理
- 用户程序:调用
-
IO
中断的进入- 当
IO
中断发生时,内核中的中断处理程序发一条消息给IO
进程,由IO
进程负责判断并处理中断
- 当
6.5 I/O进程特性
-
I/O
进程是系统进程,一般赋予最高优先级。一旦被唤醒,它可以很快抢占处理机投入运行;I/O
进程开始运行后,首先关闭中断,然后用receive
去接收消息。有两种情形:- 没有消息,则开中断,将自己阻塞
- 有消息,则判断消息类型(
IO
请求或IO
中断)
a:IO
请求
准备通道程序,发出启动IO指令,继续判断有无消息
b:IO
中断,进一步判断正常或异常结束,如果正常,则唤醒要求进入IO
操作的进程,如果是异常,则转入相应的错误处理程序。
七、I/O性能问题
解决IO
性能问题有两个方法:
- 使
cpu
利用率尽可能不被IO
降低 - 使
cpu
尽可能摆脱IO
我们可以使用缓冲技术减少或缓解速度差异,同时使用异步IO
来使cpu
不等待IO
。还可以使用DMA
、通道等IO
部件来让cpu
摆脱IO
操作。
7.1 异步I/O
-
Windows
提供两种模式的IO
操作:异步和同步 - 异步模式:用于优化应用程序的性能
- 通过异步
IO
,应用程序可以启动一个IO
操作,然后在IO
请求执行的同时继续处理 - 基本思想:填充
IO
操作时间等待的cpu
时间
- 通过异步
- 同步
IO
:应用程序被阻塞直到IO
操作完成。
7.2 同步I/O流程
- 在
IO
处理过程中,cpu
处于空闲等待状态 - 而在处理数据的过程中,不能同时进行
IO
操作
7.3 异步I/O的基本思想
- 系统实现
- 通过切换到其他线程保证
cpu
利用率 - 对少量数据的
IO
操作会引入切换的开销
- 通过切换到其他线程保证
- 用户实现
- 将访问控制分成两段进行
- 发出读取指令后继续做其他操作
- 当需要用读入的数据的时候,再使用
wait
命令等待其完成 - 不引入线程切换,减少开销
网友评论