5.I/O

输入输出的目的,简单来说,就是提供一个人机交互的通道,使得人与计算机能够进行沟通。

计算机系统中参与I/O的外设大体上可分为如下三类:

  • 人可读:适用于计算机用户间的交互,如打印机和终端。终端又包括显示器和键盘,以及其他一些可能的设备,如鼠标。
  • 机器可读:适用于与电子设备通信,如磁盘驱动器、USB密钥、传感器、控制器和执行器。
  • 通信:适用于与远程设备通信,如数字线路驱动器和调制解调器。

执行I/O的三种技术:

  • 程序控制I/O:处理器代表一个进程给I/O模块发送一个I/O命令,该进程进入忙等待,直到操作完成才能继续执行。

  • 中断驱动I/O:处理器代表进程向I/O模块发出一个I/O命令。有两种可能性:若来自进程的I/O指令是非堵塞的,则处理器继续执行发出I/O命令的进程的后续指令。若I/O指令是堵塞的,则处理器执行的下一条指令来自操作系统,它将当前的进程设置为堵塞态并调度其他进程。

  • 直接存储器访问(DMA):一个DMA模块控制内存和I/O模块之间的数据交换。为传送一块数据,处理器给DMA模块发请求,且只有在整个数据块传送结束后,它才被中断。

I/O进程

I/O进程是专门处理系统中的I/O请求和I/O中断工作的。是系统进程,一般赋予最高优先级。一旦被唤醒,它可以很快抢占处理机投入运行。当I/O进程开始运行后,首先关闭中断,然后用receive去接收消息。如果没有消息,则开中断将自己堵塞,如果有消息,就去判断消息的类型是I/O请求还是I/O中断,然后再分别处理。

  • I/O请求的进入

    • 用户程序:调用send将I/O请求发送给I/O进程。调用block将自己堵塞,直到I/O任务完成后被唤醒。
    • 系统:利用wakeup唤醒I/O进程,完成用户所要求的I/O处理。
  • I/O中断的进入

    当I/O中断发生时,内核中的中断处理程序发送一条消息给I/O进程,由I/O进程负责判断并处理中断。

    image

    当一个 I/O 设备完成它的工作后,它就会产生一个中断(默认操作系统已经开启中断),它通过在总线上声明已分配的信号来实现此目的。主板上的中断控制器芯片会检测到这个信号,然后执行中断操作。

磁盘高速缓存

高速缓冲存储器(cache memory)通常指比内存小且比内存块的存储器,它位于内存和处理器之间。这种高速缓冲存储器利用局部性原理来减少平均存储器的存取时间。同样的原理也适用于磁盘存储器。磁盘高速缓存是内存中为磁盘扇区设置的一个缓冲区,它包含有磁盘中某些扇区的副本。出现对某一特定扇区的I/O请求时,首先会进行检测,以确定该扇区是否在磁盘的高速缓存中。若在则该请求可通过这个高速缓存来满足。若不在,则把被请求的扇区从磁盘读到磁盘高速缓存中。

磁盘的高速缓存有两个问题:

  • 当一个I/O请求从磁盘高速缓存中得到满足时,磁盘高速缓存中的数据必须传送到发送请求的进程。这可以通过在内存中把这一块数据从磁盘高速缓存传送到分配给该用户进程的存储空间中,或简单地使用一个共享内存,传送指向磁盘高速缓存中相应项的指针。
  • 置换策略。当一个新扇区被读入磁盘高速缓存时,必须换出一个已存在的块。因此这就需要一个页面置换算法。
    • 最近最少使用算法(LRU,Least Recently Used)
    • 最不常使用页面置换算法(LFU, Least Frequently Used)

每个设备控制器都会有一个应用程序与之对应,设备控制器通过应用程序的接口通过中断与操作系统进行通信。设备控制器是硬件,而设备驱动程序是软件。

内存映射 I/O

每个控制器都会有几个寄存器用来和 CPU 进行通信。通过写入这些寄存器,操作系统可以命令设备发送数据,接收数据、开启或者关闭设备等。通过从这些寄存器中读取信息,操作系统能够知道设备的状态,是否准备接受一个新命令等。

为了控制寄存器,许多设备都会有数据缓冲区(data buffer),来供系统进行读写。

那么问题来了,CPU 如何与设备寄存器和设备数据缓冲区进行通信呢?存在两个可选的方式。第一种方法是,每个控制寄存器都被分配一个 I/O 端口(I/O port)号,这是一个 8 位或 16 位的整数。所有 I/O 端口的集合形成了受保护的 I/O 端口空间,以便普通用户程序无法访问它(只有操作系统可以访问)。使用特殊的 I/O 指令像是:

IN REG,PORT

CPU 可以读取控制寄存器 PORT 的内容并将结果放在 CPU 寄存器 REG 中。类似的,使用:

OUT PORT,REG

CPU 可以将 REG 的内容写到控制寄存器中。大多数早期计算机,包括几乎所有大型主机,如 IBM 360 及其所有后续机型,都是以这种方式工作的。

第二个方法是 PDP-11 引入的,它将「所有控制寄存器映射到内存空间」中。

直接内存访问

无论一个 CPU 是否具有内存映射 I/O,它都需要寻址设备控制器以便与它们交换数据。CPU 可以从 I/O 控制器每次请求一个字节的数据,但是这么做会浪费 CPU 时间,所以经常会用到一种称为直接内存访问(Direct Memory Access) 的方案。它意味着 CPU 授予 I/O 模块权限在不涉及 CPU 的情况下读取或写入内存。也就是 DMA 可以不需要 CPU 的参与。这个过程由称为 DMA 控制器(DMAC)的芯片管理。由于 DMA 设备可以直接在内存之间传输数据,而不是使用 CPU 作为中介,因此可以缓解总线上的拥塞。DMA 通过允许 CPU 执行任务,同时 DMA 系统通过系统和内存总线传输数据来提高系统并发性。为了简化,我们假设 CPU 通过单一的系统总线访问所有的设备和内存,该总线连接 CPU 、内存和 I/O 设备,如下图所示

image

DMA 工作原理

首先 CPU 通过设置 DMA 控制器的寄存器对它进行编程,所以 DMA 控制器知道将什么数据传送到什么地方。DMA 控制器还要向磁盘控制器发出一个命令,通知它从磁盘读数据到其内部的缓冲区并检验校验和。当有效数据位于磁盘控制器的缓冲区中时,DMA 就可以开始了。

DMA技术工作流程如下:

如果处理器想读或写一块数据时,它通过向DMA模块发送以下信息来给DMA模块发出一条命令:

  • 请求读操作或写操作的信号,通过在处理器和DMA模块之间使用读写控制线发送。
  • 相关I/O设备地址,通过数据线发送。
  • 从存储器中读或向存储器中写的起始地址,在数据线上传送,并由DMA模块保存在其地址寄存器中。
  • 读或写的字数,也通过数据线传送,并由DMA模块保存在其数据计数寄存器中

然后处理器继续执行其他工作,此时它已把这个I/O操作委托给DMA模块。DMA模块直接从存储器中或向存储器中逐字传送整块数据,并且数据不再需要通过处理器。传送结束后,DMA模块给处理器发送一个中断信号。因此,只有在传送开始和结束时才会用到处理器。

由于DMA需要使用内存总线,而CPU也需要使用内存总线,这样将形成内存总线竞争。那么DMA使用总线的模式将依赖于CPU使用内存的模式。根据这些模式的不同,我们可以选择周期盗用(cycle stealing)或者爆发模式(burst mode)。由于DMA传输的数据量通常较大,数据存放何处就是一个需要考虑的因素。我们既可以将数据直接存入内存,也可以存入DMA缓冲区,然后通过中断让CPU一次性将DMA缓冲区的数据拷入内存。另外一个考虑因素就是如何寻址内存。是使用虚拟地址还是物理地址?使用物理地址的好处是速度快,缺点是绕过MMU存在安全和可靠性风险。

DMA模式的优缺点优点就是将主CPU从I/O中解脱出来。而缺点自然是增加了成本和复杂性。而且,由于DMA需要与CPU竞争内存总线,其效率的提高不如理论上的期望。因此,并不是任何I/O都应该使用DMA。



results matching ""

    No results matching ""