外围设备

输入/输出操作通过连接到输入输出模块的各种外部设备完成,这些外部设备提供了在外部环境和计算机系统之间的数据交换,通常称为外围设备,简称外设

  • 人可读设备:适用于与计算机用户通信

  • 机器可读设备:适用于与设备通信

  • 通信设备:适用于与远程设备通信

不能将外设直接连接到系统总线上

  • 外设的数据传送速度一般比存储器或处理器慢得多

  • 外设使用的数据格式和字长度通常与处理器不同

I/O模块

I/O模块是计算机内部系统和外设之间的桥梁

  • 通过系统总线或中央处理器和存储器连接

  • 通过专用数据线与一个或多个外设连接

外设接口

I/O模块的接口以控制、状态和数据信号的形式出现

  • 控制逻辑:控制外设的操作,以响应来自I/O模块的命令

  • 缓冲器:缓冲器用于缓存I/O模块和外设之间传送的数据

    • 缓冲器的大小一般是8位或16位

I/O模块的功能

  1. 处理器通信

    • 命令译码:I/O模块接受来自处理器的命令,这些命令一般作为信号发送到控制总线

    • 数据:数据是在处理器和I/O模块之间经由数据总线来交换的

    • 状态报告:由于外设速度很慢,所以知道I/O模块的状态很重要

    • 地址识别:I/O模块必须能识别它所控制的每个外设的唯一地址

  2. 设备通信

    通信内容包括命令、状态信息、数据

  3. 数据缓冲

    外设的数据传送速度一般比存储器或处理器的慢得多

    • 某些外设的数据传送速度比存储器或处理器要快

  1. 控制和定时

    处理器会非预期的与一个或几个外设进行通信

    一些内部资源是被共享的,如主存和数据总线

  2. 检错

    检错并把差错信息报告给处理器

    • 设备报告的机械和电路故障

    • 传输过程中数据位的变化

I/O模块结构

外部接口

  1. 并行接口:多跟线连接I/O模块和外设,同时传送多位数据

  2. 串行接口:只有一根线用于传输数据,每次只传输一位数据

由于并行接口要求每次同时传送,当传输速度和总线长度增加时,总线的时钟频率会受到限制

I/O操作技术

传递方式 无中断 使用中断
I/O与存储器之间的传递通过处理器实现 编程式I/O 中断驱动式I/O
I/O与存储器直接传送 直接存储器存取
  1. 编程式I/O

    处理器通过执行程序来直接控制I/O操作,当处理器发送一条命令到I/O模块时,它必须等待,直到I/O操作完成

  1. 中断驱动式I/O

    处理器发送一条I/O命令后,继续执行其他指令,并且当I/O模块完成其工作后,才去中断处理器工作

  1. 直接存储器读取

    I/O模块与主存直接交换数据,而不需要处理器的干涉

编程式I/O

  • 当处理器在执行过程中遇到一条与I/O操作有关的指令时,它通过发送指令到适当的I/O模块来执行这条指令

  • I/O模块将执行所要求的动作,然后在I/O状态寄存器中设置一些适当的位

  • I/O不会中断处理器,因此处理器需要周期性地检查I/O模块的状态,直到发现该操作完成

I/O命令

为了执行I/O操作,处理器发送一个指定具体I/O模块和外设的地址,并发送一条I/O命令

  1. 控制命令:激活外设并告诉它要做什么

  2. 测试命令:测试I/O模块及其外设相关的各种状态条件

  3. 读命令:使I/O模块从外设获得一个数据,把它存入内部缓冲区

  4. 写命令:使I/O模块从数据总线获得一个数据,把它传入外设

I/O指令

I/O指令很容易映射为I/O命令,并且两者之间通常是简单的一一对应关系

  • 指令的形式取决于外设寻址的方式

编制方式:

  • 存储器映射式I/O:存储单元和I/O设备有统一的地址空间

    • 能用大的指令系统,可进行更有效的编程
  • 分离式I/O:让总线既有存储器的读线和写线,同时也有输入和输出命令线

中断驱动式I/O

  • 处理器发送一个I/O命令到模块,然后去处理其它有用的工作

  • 当I/O模块准备和处理器交换数据时,它中断处理器以请求服务

  • 处理器执行数据传送,最后恢复它原先的处理工作

从I/O模块的角度看

  1. I/O模块接收来自处理器的读命令

  2. I/O模块从相关的外设中读入数据

  3. 一旦数据进入I/O模块的数据寄存器后,该模块通过控制总线给处理器发送中断信号

  4. I/O模块等待直到处理器请求该数据时为止

  5. 当处理器有数据请求时,I/O模块把数据传送到数据总线上,并准备另一个I/O操作

从处理器的角度看

  1. 处理器发送一个读命令

  2. 处理器离开去做其它的事情,并在每个指令周期结束时检查中断

  3. 当来自I/O模块的中断出现时,处理器保存当前程序的现场

  4. 处理器从I/O模块读取数据字并保存到主存中

  5. 处理器恢复刚才正在运行的程序的现场,并继续运行原来的程序

中断禁止和中断允许

中断要把上下文环境放置到栈中

有些正在处理中关于数据读取等操作不可以直接打断

响应优先级和处理优先级

假设响应优先级为 $L_1 > L_2 > L_3 > L_4$,处理优先级为 $L_1 > L_4 > L_3 > L_2$,而 $L_1,L_3,L_4$ 在主程序运行时同时发生了中断请求,而 $L_2$ 的中断请求发生在处理 &L_3& 中断的时候

  • 屏蔽字是由处理优先级来进行处理的

    • 每一个都能屏蔽自己

    • 如上的屏蔽字中,行屏蔽列

设备识别

  • 多条中断线:即使有多条中断线可用,每条线上也需要采用其他三种技术中的一种

  • 软件轮询:轮询每一个I/O模块来确定是哪个模块发生的中断

  • 菊花链:所有的I/O模块共享一条中断请求线,中断应答线采用菊花链穿过这些中断模块

  • 独立请求:特定的中断控制器用于解码和分析优先级

分配优先级

  • 多条中断线:处理器仅仅挑选具有最高优先级的中断线

  • 软件轮询:模块的轮询次序就决定了模块的优先级

  • 菊花链:链接模块次序就决定了模块的优先级

  • 独立请求:中断控制器决定

直接存储器存取

无需经过处理器即可访问内存的模块

不足

  1. I/O传输速率受处理器测试和服务设备的速度限制

  2. 处理器负责管理I/O传送,对于每一次I/O传送,处理器必须执行很多指令

DMA模块

  • 处理器通过发送以下信息向DMA模块发出命令:读/写、I/O设备地址、内存中的起始位置、字数

  • 处理器继续进行其他工作

  • DMA模块将全部数据块,每次一个字,直接将数据传输到存储器或从存储器读出,而无需经过处理器

  • 当传输完成时,DMA模块向处理器发送一个中断信号

内存权限

CPU停止法

优点:控制简单

缺点:影响CPU,没有充分利用内存

适用:高速I/O设备的块传输

周期窃取

优点:充分利用CPU和内存,及时响应I/O请求

缺点:DMA每次都请求总线

适用:I/O周期大于存储周期

交替分时访问

优点:CPU未停止或等待,DMA不请求总线

缺点:CPU周期大于存储周期

DMA配置机制

单总线分离DMA

所有模块共享相同的系统总线

DMA模块使用编程式I/O,通过DMA模块在存储器和I/O模块之间交换数据

  • 便宜但低效
单总线集合的DMA-I/O

DMA逻辑实际上可能是I/O模块的一部分,也可能是控制一个或多个I/O模块的单独模块

  • 减少周期数

I/O总线

使用I/O总线将I/O模块连接到DMA模块

  • 多个I/O模块共享DMA,且容易扩展

I/O模块的演变

  • CPU直接控制外设

  • 增加控制器或I/O模块,CPU使用编程式I/O,将CPU与外围设备的细节分离

  • 采用中断,CPU无需花费时间等待外围设备就绪

  • I/O模块可通过DMA直接存取存储器,无需CPU负责存储器和I/O模块之间的数据传递

  • I/O通道:I/O模块有自己的处理器,带有专门为I/O操作定制的
    指令集

    • CPU指示I/O通道执行存储器中的I/O指令,只有在执行完成后才会中断CPU
  • I/O处理器:I/O模块有一个局部存储器,I/O模块成为一个自治的计算机,常用于与交互式终端进行通信

    • 只需最少的CPU参与即可控制大量I/O设备

概述

类型:

  1. 系统总线:连接CPU、存储器、I/O控制器和其他功能设备

  2. 通信总线:连接主机和I/O设备,或连接不同的计算机系统

设计要素:

  1. 用途

    • 专用总线、复用总线
  2. 仲裁

    • 集中式、分布式
  3. 时序

    • 同步、异步、半同步、分离事务
  4. 总线带宽和数据传输速率

  5. 总线层次结构

    • 单总线、双总线、多总线

总线结构

  1. 数据线:在系统组件之间传输数据

    • 数据线的数量决定了一次可以传输的数据的大小
  2. 地址线:在数据线和地址I/O端口上指定数据的来源和去向

    • 地址线的数量决定了寻址空间的大小
  3. 控制线:控制对数据线和地址线的存取和使用

    • 时钟:用于总线同步操作

    • 总线请求:表示模块需要获得对总线的控制

    • 总线允许:发出请求的设备已经被允许控制总线

    • 中断请求:表示某个中断正悬而未决

    • 中断响应:未决的中断请求被响应

    • 存储器读:从存储器读数据到总线

    • 存储器写:将数据从总线写入存储器

    • I/O读:从I/O端口读数据到总线

    • I/O写:将数据从总线写入I/O端口

总线上数据传输的特点

  1. 总线可以被多个设备监听,但同一时刻只能由一个设备发送数据

    • 如果同一时刻多个设备同时发送数据,会造成数据之间的混淆

    • 总线被使用时,其他设备不能抢占

  2. 如果连在总线上的某个设备希望向另一个设备发送数据,需要:

    • 获得总线的使用权

    • 通过总线传送数据

  3. 如果连在总线上的某个设备希望向另一个组件请求数据,需要:

    • 获得总线的使用权

    • 通过总线向另一个设备发送请求,等待另一个设备发送数据

用途

  1. 专用总线:始终只负责一项功能,或始终分配给特定的计算机组件

  2. 复用总线:将同一线路用于多种用途

仲裁

总线仲裁:当多个设备需要与总线通信时,通过某种策略选择一个设备

平衡因素

  • 优先级:优先级高的设备优先被服务

  • 公平性:优先级最低的设备不能一直被延迟

仲裁方案

  1. 集中式:由仲裁器或总线控制器负责分配总线使用权

    • 链式查询/菊花链

    • 计数器查询

    • 独立请求

  2. 分布式:每个设备都包含访问控制逻辑,各设备共同作用分享总线

    • 自举式

    • 冲突检测

链式查询

所有的设备都是串行连接的,并允许信号从优先级最高的设备下发到优先级最低的设备

  • 总线仲裁器收到请求后,在总线不忙的前提下,发起允许信号

  • 如果某个设备收到了允许信号并且发起了总线请求,该设备将总线设置为繁忙状态,允许信号将不再被进一步传递

PPT - 第2 章总线与接口芯片PowerPoint Presentation, free download - ID:3756437

优点

  1. 确定优先级简单

  2. 可以灵活地添加设备

缺点

  1. 不能保证公平性

  2. 对电路故障敏感

  3. 限制总线的速度

计数器查询

将总线允许线替换为设备ID线

  • 如果总线空闲,总线仲裁器通过设备ID线发送计数

  • 如果当前发送请求的设备ID等于总线仲裁器当前的计数,中线仲裁器将停止计数,并将总线设置为忙

第3章系统总线| MyBlog - GxkOrd

优点

  1. 通过使用不同的初始计数,可以灵活确定设备优先级

    • 强调优先级:从1开始

    • 强调公平性:从下一个设备的ID开始

  2. 对电路故障不敏感

缺点

  1. 需要添加设备ID线

  2. 需要解码和比较设备ID信号

  3. 限制总线的速度

独立请求

每个设备都有自己的总线请求线和总线允许线,且直接连接到总线仲裁器

  • 当一个设备请求总线时,它通过总线请求线将请求信号发送给总线仲裁器

  • 总线仲裁器决定哪个设备可以使用总线

    • 固定优先级、公平链式、LRU、FIFO、$\cdots$

了解计算机系统的总线- 墨天轮

优点

  1. 快速响应

  2. 可编程的优先级

缺点

  1. 复杂的控制逻辑

  2. 更多的控制线路

自举式

每个设备在其总线请求线上发送请求,固定优先级,自行判断自己是否在请求总线地设备中优先级最高

  • 最低优先级的设备没有请求线

  • 箭头最少的优先级最高

冲突检测法

冲突:如果两个设备发现总线空闲,它们可能同时使用总线

  • 在传输数据时,设备会监听总线,检查是否存在冲突

  • 如果发生冲突,所有使用总线的设备将停止数据传输,并分别在随机间隔时间后再次请求总线

时序

确定每个总线事物的开始和结束时间

  • 总线事务:地址 + 数据 + $\cdots$ + 数据

类型:同步时序、异步时序、半同步、分离事物

同步时序

时间的发生由始终决定

优点

  1. 更容易实现和测试

缺点

  1. 所有设备共享一个时钟

  2. 总线长度受到时钟偏差的限制

    • 同步总线很短,不然会出现时钟混乱
  3. 数据过长会导致不同步,造成问题

异步时序

一个时间的发生取决于前一个事件的发生

分为非互锁、半互锁、全互锁三个阶段(使用握手规则

  • 蓝色表示先后关系,也就是“一次握手”

  • 非互锁(第一次握手):我告诉你我准备好了

  • 半互锁(第二次握手):我告诉你我已经收到了

    • “我准备好了”信号只能在你说“我收到了”之后才能撤回
  • 全互锁(第三次握手):我知道了你知道“收到了”之后才能撤回

优点

  1. 可以灵活地协调速度不同的设备

缺点

  1. 接口逻辑复杂

  2. 对噪声敏感

异步数据传输

  1. CPU设置地址并设置ReadReq线

    • 存储器读取相应地址
  2. 存储器读取相应地址并设置Ack线

    • CPU释放地址线和ReadReq线
  3. CPU释放地址线和ReadReq线

    • 存储器释放Ack线
  4. 存储器释放Ack线

    • 存储器将数据传到数据线
  5. 存储器将数据传到数据线并设置DataRdy线

    • CPU读取数据
  6. CPU读取数据并设置Ack线

    • 存储器释放数据线和DataRdy线
  7. 存储器释放数据线和DataRdy线

    • CPU释放Ack线

半同步时序

同步时序和异步时序相结合

为了减少噪声的影响,在异步计时中使时钟

  • 准备和响应信号在时钟上升沿有效

分离事务

设备准备数据期间释放总线,将一个总线事件分离为两个过程

优点

  1. 增加总线利用率

缺点

  1. 增加每个总线事件地持续时间和系统复杂度

  • 将两个信号之间的总线释放出来

总线带宽和数据传输速率

总线带宽:总线的最大数据传输速率

  • 不考虑总线仲裁、数据传输等因素

数据传输速率

  • 考虑地址传输、握手等因素

总线宽度:组成总线的线数

  • 数据总线越宽,一次传输的数据位数就越多

  • 地址总线越宽,一次传输的地址位数就越多

例子:

我们假设同步总线的时钟周期为50ns,并且每一次数据传输需要一个时钟周期,异步总线每次握手需要40ns。两种总线均为32位宽,并且数据的准备时间均为200ns,计算当总线从内存中读取一个字(32位)的时候的数据传输率

  1. 同步总线

    数据传输率:$\frac{32bit}{(50 + 200 +50)ns} = 106.7Mbps$

    • 发送指令和地址到内存:50ns

    • 内存准备数据:200ns

    • 将数据传输到CPU:50ns

  1. 异步总线

    数据传输率:$\frac{32bit}{(40 + 200 +120)ns} = 106.7Mbps$

    • 步骤1:40ns

    • 步骤2、3、4 / 数据准备:$max((40 \times 3) ns,200ns)$

    • 步骤5、6、7:$(40 \times 3)ns$

  • 如果把存储器的数据准备时间改为230ns,则同步总线的数据准备时间应该是250ns,异步总线仍是230ns

    • 同步总线一个时间周期不可以做两件事情

不同数据块大小的数据传输速率

假设系统存在以下特征:

  • 支持访问大小为4到16个字(每个字32位)的块

  • 同步总线具有64位宽和200MHz时钟频率,需要1个时钟周期来传输地址或64位数据

  • 在两个总线事务之间有2个空闲时钟周期

  • 内存访问时准备前4个字需要200ns,后面每4个字准备需要20ns

  • 当前面的数据在总线上传输时,内存可以同时读取后面的数据

如果读取256个字,分别计算每次传输4个字和16个字时的数据传输速率、传输时间和每秒总线事务数:

  1. 每次传输4个字

    总线事务:地址 + 4个字

    • 地址传输:1个时钟周期

    • 数据准备:200ns(40个时钟周期)

    • 数据传输:2个时钟周期

    • 空闲:2个时钟周期

      总共:$\frac{256}{4} \times (1+40+2+2) = 2880$ 个时钟周期

      传输时间:$2880 \times 5ns = 14400ns$

      每秒总线事务数:$\frac{64 \times 1s}{14400ns} = 4.44M$

    • 乘以64是因为:计算的总时间是传输256,而非一个总线事务

      数据传输速率:$\frac{256 \times 32bit}{14400ns} = 568.9Mbps$

  2. 每次传输16个字

    总线事务:地址 + 16个字

    • 地址传输:1个时钟周期

    • 数据准备(前4个字):200ns(40个时钟周期)

    • 数据传输:2个时钟周期(同时读取后4个字:20ns

    • 空闲:2个时钟周期

      总共:$\frac{256}{16} \times (1+40+3 \times max(2,4)+2+2) = 912$ 个时钟周期

      传输时间:$912 \times 5ns = 4560ns$

      每秒总线事务数:$\frac{16 \times 1s}{4560ns} = 3.51M$

    • 乘以16是因为:计算的总时间是传输256,而非一个总线事务

      数据传输速率:$\frac{256 \times 32bit}{4560ns} =1796.5Mbps$

提高总线数据传输率

  1. 增加时钟频率

  2. 增加数据总线宽度

    • 每次传输更多数据
  3. 块传输

    • 传输一次地址就传输一块数据
  4. 分离总线事务

    • 减少总线空闲时间
  5. 分离地址线和数据线

    • 同时传输地址和数据

总线层次结构

单总线结构

CPU、存储器、I/O模块都连接到一条系统总线

优点

  1. 简单,易于扩展

缺点

  1. 连接的设备越多,总线长度越大,传输延迟也就越大

  2. 聚集的传输请求接近总线容量时,总线成为瓶颈

双总线结构I

在CPU和存储器中间增加一个存储器总线

优点

  1. 增加CPU和存储器之间的传输效率,同时降低系统总线的负担

双总线结构II

将系统总线分为存储器总线、I/O总线和IOP(input/output processer)

优点

  1. 降低I/O对总线的负担

多总线结构I

增加一个本地总线来连接CPU和Cache

优点

  1. 分离了CPU和I/O的交互

多总线结构

将系统总线分为存储器总线、I/O总线和DMA总线

优点

  1. 增加I/O效率

多总线结构III

增加一个高速I/O总线来连接高速设备

优点

  1. 增加I/O交互效率

微操作

执行程序时,计算机操作是由一系列指令周期组成的

  • 每个周期执行一条机器指令

每个指令周期可以看作是由几个更小的子周期组成

  • 取指、间指、执行、中断

微操作:每个子周期由一系列涉及CPU寄存器操作的更小步骤组成

微操作分组原则

  1. 事件流动顺序必须是恰当的

  2. 必须避免冲突

    • $MBR \leftarrow 内存$ 和 $IR \leftarrow MBR$ 不应出现在同一时间单位
  3. 所用的时间单位尽可能少

取指周期

出现在每个指令周期的开始,将指令从存储器中取出

  • 时间要尽可能少,提高效率

  • 涉及同一个设备或具有逻辑先后顺序的不能同时进行

间址周期

若指令采用间接寻址,则在指令执行前有一个间址周期

执行周期

对于不同的操作码,会出现不同的微操作序列

  1. 加法指令

  1. 转移并保存地址指令

中断周期

在完成执行周期时,要确定是否有允许的中断产生

  • 如果有,则出现一个中断周期

  • $MAR \leftarrow Save_Address$ 和 $Memory \leftarrow (MBR)$ 划掉

指令周期代码

取指、间址、中断周期各有一个微操作序列,执行周期对于每个操作码有一个微操作序列

指令周期代码:假设一个2位的ICC寄存器,明确CPU处于指令周期哪个阶段

  • 00:取指

  • 01:间址

  • 10:执行

  • 11:中断

控制器

CPU内部总线

ALU和寄存器都连在CPU内部总线上

为了数据在该内部总线和各寄存器之间传递,内部总线和寄存器之间有门和控制信号

控制线控制着数据和系统总线(外部)的交换以及ALU的操作

控制CPU的功能需求

  1. CPU的基本元素

    • ALU、寄存器组、内部数据通路、控制器、外部数据通路
  2. CPU需要完成的微操作

    • 在寄存器之间传送数据

    • 将数据由寄存器传送到外部接口(如系统总线)

    • 将数据由外部接口传送到寄存器

    • 将寄存器作为输入和输出,完成算术和逻辑运算

  3. 控制器的两个基本任务

    • 定序:根据正被执行的程序,控制器使CPU以正确的顺序通过一系列微操作

    • 执行:控制器使每个微操作得以完成

控制器的输入和输出

输入

  • 指令寄存器:当前指令的寻址方式和操作码

  • 标志:确定CPU状态和前一个ALU操作的结果

  • 时钟:控制器要在每个时钟脉冲完成一个或一组同时的微操作

  • 来自控制总线的控制信号:向控制器提供控制信号

输出

CPU内的控制信号

  • 用于寄存器之间传送数据

  • 用于启动特定的ALU功能

到控制总线的控制信号

  • 到存储器的控制信号

  • 到I/O模块的控制信号

所有控制信号最终作为二进制输入量直接输入到各个逻辑门上

控制信号

所有控制信号最终都作为二进制输入直接应用于各个逻辑门

三种控制信号:

  • 激活ALU的功能

  • 激活数据通路

  • 通过系统总线或其他外部接口传递来的信号

举例:

  1. 传送PC的内容到MAR

    • 打开$C_2$:PC传到MAR
  2. 由存储器读一条指令装入MBR,并且递增PC

    • 打开$C_0$:MAR的内容送到地址总线上

    • 存储器读控制信号$C_R$送到控制总线上

    • 打开$C_5$:数据总线上的内容存入MBR

    • 控制信号对PC内容加以,并把结果存回PC

  3. 传送MBR的内容到IR

    • 打开$C_4$:MBR的内容送到IR

  • 小圆点表示的是,$C_R$是读信号

  • 一个固定长度二进制串用来控制相应的门的开关

控制器的最小特性

  1. 它只需要知道将被执行的指令和算术、逻辑运算结果的性质(比如正负、溢出等)

    • 不需要知道正被处理的数据或得到的实际结果是什么
  2. 它只是以少量的送到CPU内的和送到系统总线上的控制信号来实现控制

控制器实现

  1. 硬布线实现

    • 控制器是一个组合电路,把输入逻辑信号转换为一组输出逻辑信号,即控制信号
  2. 微程序实现

    • 控制逻辑是微程序指定的,控制器是一个相对简单的逻辑电路,通过执行每条微指令来产生控制信号

硬布线实现

  • 标志和控制总线信号:每位都有特定意义

  • 指令寄存器:通过译码使得每一个操作码有一个唯一的逻辑输入

    • $n$个输入 $\rightarrow$ $2^n$个输出
  • 时钟:在一个时钟周期内,控制器在不同时间单位发送不同的控制信号

    • 使用一个定时器作为控制器的输入,并且控制器在指令周期结束时必须通知定时器使其重新开始计数

    • 时钟脉冲的周期必须足够长,以允许信号沿数据路径和通过处理器电路传播

控制器逻辑

为每个输出的控制信号设计一个关于控制器输入的布尔表达式

定义两个控制信号 $P$ 和 $Q$

  • $PQ = 00$:取指周期

  • $PQ = 01$:间址周期

  • $PQ = 10$:执行周期

  • $PQ = 11$:中断周期

举例:

$C_5$:使外部数据总线上的数据读入MBR

  1. $C_5$ 在取指和间址周期的第二个时间单位有效:

    • $C_5 = \bar{P} \cdot \bar{Q} \cdot T_2 + \bar{P} \cdot Q \cdot T_2$
  2. $C_5$ 在执行周期也有效:

    • $C_5 = \bar{P} \cdot \bar{Q} \cdot T_2 + \bar{P} \cdot Q \cdot T_2 + P \cdot \bar{Q} \cdot (LDA + ADD + AND) \cdot T_2$

微程序实现

微程序基于硬件和软件之间

微指令:每行描述一个时间内出现的一组微操作

基本思路:

  1. 对于每个微操作,控制器的任务是产生一组控制信号

  2. 构造一个控制字,每位代表一根控制线

    • 这样每个微操作能用控制字中不同的0和1的样式来表示
  3. 将这些控制字串在一起,可以表示控制器需要完成的微操作序列

由于每个微操作的顺序不是固定的,控制字被放入存储器中,每个字都有一个唯一的地址

  • 添加少数几位用于指示条件的真假

    • 假则顺序执行下一条指令

    • 真则地址字段指向的微指令是下一条执行的微指令

  • 地址字段:指示条件为真时,将要执行的下一控制字的位置

微程序执行

微程序控制器构成
  1. 定序逻辑:向控制地址寄存器装入地址,并发出读命令

  2. 控制地址寄存器:含有下面即将被读取的微指令地址

  3. 控制存储器:存有一组微指令

  4. 控制缓冲寄存器:存放被读出的微指令

微程序控制器任务
  1. 微指令定序

    根据当前的微指令、条件标志和指令寄存器的内容,产生下一微指令的控制存储器地址

    1. 双地址字段:在每条微指令中提供两个地址字段,选择并发送其中某一个地址或操作码到控制地址寄存器

    2. 单地址字段:下一个地址得选择可以是地址字段或下一个顺序地址

    3. 可变格式:提供两种完全不同的指令格式,一位字段用于指定哪种格式被使用

      设计考虑:

    4. 微指令的大小

    5. 地址生成时间

  2. 微指令执行

    产生控制信号:发往CPU内部,送往外部控制总线或其他外部接口

微程序控制器工作流程
  1. 为执行一条指令,定序逻辑发出一个读命令给控制存储器

  2. 当一条微指令由控制存储器读出后,被传送到控制缓冲寄存器

    • 从控制地址寄存器读
  3. 控制缓冲寄存器的内容生成控制信号,并为定序逻辑提供下一条地址信息

    • 控制缓冲寄存器的左半部分与控制器发出的控制线相连

    • 由控制存储器读一条微指令等同于执行这条微指令

  4. 定序逻辑根据这个地址信息和ALU标志,将新的地址装入到控制地址寄存器

生成新地址的三个选择:

  1. 取顺序下一条微指令:加1到控制地址寄存器

  2. 基于跳转微指令转移到一个新的例程:将控制缓冲寄存器的地址字段装入控制地址寄存器

  3. 转移到一个机器指令例程:根据IR总的操作码向控制地址寄存器装入机器指令例程的第一条微指令

CPU

CPU任务

  • 取指令:从存储器读取指令

  • 解释指令:对指令进行译码,以确认所要求的动作

  • 取数据:指令的执行可能要求从存储区或I/O模块中读取数据

  • 处理数据:指令的执行可能要求对数据完成某些算数或逻辑运算

  • 写数据:执行的结果可能要求写数到存储器或I/O模块

CPU需求

CPU需要一些小容量的内部存储器

  1. CPU需要在指令周期中临时保存指令和数据

  2. CPU需要记录当前所执行指令的位置,以便知道从何处得到下一条指令

控制和状态寄存器

  1. 存储地址寄存器:MAR

    • MAR直接到地址总线

    • 不仅仅是存储指令的地址,而是可以存储所有的数据地址

  2. 存储缓冲(数据)寄存器:MBR/MDR

    • 包含要写入内存的数据字或最近读取的数据字

    • MBR直接连接到数据总线

    • 可以直接访问MBR和用户可见寄存器

  3. 程序计数器:PC

    • 处理器在每次取指令后就更新PC

    • 分支或跳过指令也会修改PC的内容

  4. 指令寄存器:IR

    • 获取的指令呗加载到IR中,在IR中分析操作码和操作数说明符
  5. 程序状态字:PSW

    一个或一组寄存器包含状态信息

    • Sign:最后一次算术运算结果的符号位

    • Zero:结果为0时设置

    • Carry:有进位或出位则设置

    • Equal:设置逻辑比较结果是否相等

    • Overflow:表示算术溢出

    • Interupt:启用或禁用中断

    • Supervisor:指示处理器是以Supervisor模式还是用户模式执行

数据流

取指周期

  1. 把下一条指令地址放到MAR中,然后交给内存
  1. 控制单元设置控制线的信号,如果控制线设置为相应信号,内存会始终监听信号线

    • 当读到读信号时,则会从MAR中读出一个地址,然后取出数据给数据总线
  2. 将数据从数据总线读到MBR中,然后拷贝到IR中

间址周期

  1. MBR中是地址,将地址拷贝到MAR中

  2. 控制单元发送读请求,内从从MAR中进行拉取后,从内存中取出来,返给MBR

中断周期

  1. 控制单元会先告诉主存有写操作

  2. 之后控制单元会为MAR指定一个写入的位置

指令流水线

指令流水线:一条指令的处理过程分成若干个阶段,每个阶段由相应的功能部件完成

两阶段方法

将指令处理分为两个阶段:取指令、执行指令

  • 在当前指令的执行期间取下一条指令

问题

  1. 执行时间一般长于取指时间

  2. 可能出现内存访问冲突

  3. 条件分支指令使得待取的下一条指令的地址是未知的

六阶段方法

为了进一步的加速,流水线必须有更多阶段,各个阶段所需要的时间几乎是相等的

  1. 取指令(FI):读下一条指令到缓冲器

  2. 译码指令(DI):确定操作码和操作数指定符

  3. 计算操作数(CO):计算每个源操作数的有效地址

  4. 取操作数(FO):从存储器取出每个操作数,寄存器中的操作数不用取

  5. 执行指令(EI):完成指定的操作,若有指定的目的操作数的位置,则将结果写入此位置

  6. 写操作数(WO):将结果存入存储器

不是所有指令都包含6个阶段

  • LOAD指令不需要WO阶段

不是所有阶段都能并行完成

  • FI、FO、WO都涉及存储器访问

限制

  1. 若6个阶段不全是相等的时间,则会在各个流水阶段涉及某种等待

  2. 条件分支指令可以是使多个指令获取无效

  • 如果调到了15号指令,则之前的所有的数据都被“浪费掉”

问题

  1. 最多的时候会同时处理6件事情,所以需要遵守6个任务中时间最长的任务所需时间

  2. 微指令之间存在时间间隔,所以6个指令加起来的运算时间要大于原来一次计算完

  3. 可能出现内存冲突

流水线性能

假设:

  • $t_i$:流水线第 $i$ 段的电路延迟时间

  • $t_m$: 最大段延迟(通过耗时最长段的延迟

  • $k$:指令流水线段数

  • $d$:锁存延时(数据和信号从上一段到下一段所需的段间锁存接收时间

周期时间:$t = max[t_i] + d = t_m + d$

令 $T_{k,n}$ 为 $k$ 阶段流水线执行所有 $n$ 条指令所需的总时间,则:

  • $T_{k,n} = [k + (n - 1)] t$

  • 加速比:$S_k = \frac{T_{1,n}}{T_{k,n}} = \frac{nkt}{[k + (n - 1)]t} = \frac{nk}{k + (n - 1)} = \frac{n}{1 + \frac{n - 1}{k}}$

误解:流水线中的阶段数越多,执行速度越快

  • 会造成指令间隔变多,间隔浪费的时间也会增加

  • 会造成指令控制比较复杂

原因

  • 在管道的每个阶段,将数据从一个缓冲区移动到另一个缓冲区以及执行各种准备和传递功能都会涉及一些开销

  • 处理内存和寄存器依赖项以及优化管道使用所需的控制逻辑量随着阶段数的增加而大大增加

冒险(Hazard)

在某些情况下,指令流水线会阻塞或停顿(stall),导致后续指令无法正确执行

类型:

  • 结构冒险(硬件资源冲突)

  • 数据冒险(数据依赖性)

  • 控制冒险

结构冒险

已进入流水线的不同指令在同一时刻访问相同的硬件资源

解决:使用多个不同的硬件资源,或者分时使用同一个硬件资源

  • 可以分时复用:前半段读出,后半段写入

数据冒险

未生成指令所需要的数据

解决

  1. 插入nop指令(空操作)

  1. 插入bubble(等待)

  1. 转发(forwarding)/ 旁路(bypassing)
  • 旁路:添加一根线来获取目标数据

  1. 交换指令顺序

控制冒险

指令执行顺序被更改

  • 转移、中断、异常、调用/返回

解决

  1. 取多条指令

    • 多个指令流:复制流水线的开始部分,并允许流水线同时取这两条指令,使用两个指令流

    • 预取多支目标:识别出一个条件分支指令时,除了取此份之指令之后的指令外,分支目标处的指令也被取来

    • 循环缓冲器:由流水线指令取指阶段维护的一个小的但极高速的存储器,含有n条最近顺序取来的指令

  2. 分支预测

    • 静态预测:

      • 预测绝不发生

      • 预测总是发生

      • 依操作码预测

    • 动态预测:

      • 发生/不发生切换

      • 转移历史表

概述

指令是计算机处理的最基本单位,采取多周期实现方案

  • 操作码 + 操作数

  • 取指令,译码/取寄存器,执行/有效地址/完成分支,访问内存,存储结果

指令表示

指令由一个位串来表示

指令格式:对于指令的个要素,这个位串划分成几个字段

  • 大多数指令集使用不止一种指令格式

机器指令符号表示法

  1. 操作码缩写成助记符,比如 ADD、SUB 等

  2. 操作数也可以用符号表示

    • 寄存器编号或内存地址

操作码

所有计算机上都会存在相同的常用操作类型,比如数据传送、算数运算、逻辑运算、转换、输入/输出、系统控制、控制转移

操作数

常见类型:地址、数值、字符、逻辑数据

地址

一个指令需要有4个地址引用:2个源操作数,1个目的操作数、1个下一指令地址

  • 下一指令地址是隐含

每条指令中的地址数目越少,指令的长度越短,不需要复杂的CPU,但是程序总的指令条数更多,执行时间更长,程序更长更复杂

数值

计算机存储的数值是受限的

字符

国际参考字母表IRA / 美国信息交换标准码ASCII:每个字符被表示为唯一的7位二进制串

扩展的二进制编码的十进制交换码EBCDIC:8位编码

统一码Unicode:16位/32位

逻辑数据

将一个n位单元看成是由n个1位项组成,每一项有值0或1

大端序和小端序

大端序:把数据高位放在低地址

小端序:把数据低位放在低地址

  • 两种策略中每个数据项有同样地址

  • 端序不影响结构中的数据项的次序

操作数的引用

寻址方式立即寻址、直接寻址、简介寻址、寄存器寻址、寄存器间接寻址、偏移寻址、栈寻址

记号

  • A:指令中地址字段的内容

  • R:指向寄存器的指令地址字段的内容

  • EA:被访问位置的实际地址

  • (X):存储器位置X或寄存器X的内容

立即寻址

操作数实际出现在指令中

  • 除了取指令之外,获取操作数不要求另外的存储器访问

  • 数的大小受限于地址字段的长度

直接寻址

地址字段含有操作数的有效地址

  • 只要求1次存储器访问,且无需为生成地址而专门计算

  • 地址空间有限

间接寻址

地址字段指示一个存储器字地址,而此地址保存有操作数的全长度地址

  • 第一层地址指向第二层的实际地址

  • 扩大了地址空间

  • 取操作数需要2次访问存储器

寄存器寻址

地址字段指示的是寄存器

  • 寄存器存的是操作数

  • 指令中仅需要一个较小的地址字段,而不需要存储器访问

  • 地址空间十分有限

寄存器间接寻址

地址字段指示寄存器

  • 寄存器存的是操作数地址

  • 扩大地址空间,比间接寻址少1次存储器访问

  • 相对于寄存器寻址,需要多1次存储器访问

偏移寻址

结合直接寻址和寄存器间接寻址能力

  • 实际地址:寄存器存放的地址 + 直接指示的地址

相对寻址

隐含引用的寄存器是程序计数器(PC)

  • 实际地址:下一条指令的地址 +直接指示的地址

基址寄存器寻址

引用的寄存器含有一个存储器地址,地址字段含有偏移量(通常是无符号整数)

  • 实际地址:寄存器存放的地址 + 直接指示的偏移量

  • 寄存器引用可以是显式的,也可以是隐式的

变址寻址

指令地址字段引用一个主存地址,被引用的寄存器含有的对该地址的一个正的偏移量

  • 实际地址:直接指示的地址 + 寄存器存放的偏移量

栈寻址

栈指针保存在寄存器中,对寄存器中栈位置的访问实际上是一种寄存器间接寻址方式

  • 与栈相关的是一个指针,它的值是栈顶地址,或者当栈顶的两个元素已在CPU寄存器内,此时栈顶指针指向栈顶的第三个元素

指令格式

指令格式通过它的各个构成部分来定义指令的位安排

  • 一个指令格式必须包含一个操作码,以及显式或隐式的、零个或多个操作数

  • 必须显式或隐式地为每个操作数指定其寻址方式

大多数指令集使用不止一种指令格式

设计原则

  1. 指令尽量短

    • 占用存储空间小
  2. 有足够的操作码位数

    • 要为操作类型不断增加预留
  3. 操作码地编码必须有唯一的解释

  4. 指令长度是字节地整数倍

    • 内存是按字节寻址
  5. 合理选择地址字段的个数

  6. 指令尽量规整

指令长度

指令长度应该是字符长度或定点数长度的整数倍

指令长度应该等于存储器的传送长度(数据总线宽度)

  • 或者这两个值其中之一是另一个的整数倍

最明显的权衡考虑是在强有力的指令清单和节省空间之间进行

  • 编程人员希望更多的操作码、更多的操作数、更多的寻址方式和更大的地址范围

  • 指令长度变短可以节省存储空间和减少数据传送时间

位的分配

对于给定的指令长度,在操作码数目和寻址能力之间存在着权衡考虑

  1. 使用变长的操作码

    • 使用一个最小操作码长度,但是对于某些操作码,可以使用指令附加位的方式来指定附加的操作
  2. 使用寻址位的考虑因素

    • 寻址方式的种数、操作数的数量、寄存器与存储器比较、寄存器组的数目、地址范围、寻址粒度

      • 能用于操作数引用的寄存器越多,指令需要的位数越少

      • 对于固定数目的寄存器,功能上的分开将是指令只需较少的位数

      • 使用较大的字时,需要的地址位更少

变长指令

提供不同长度的各种指令格式

  • 取至少等于最长指令长度的几个字节或几个字

优点:

  • 易于提供大的操作码清单,而操作码具有不同的长度

  • 寻址方式能更灵活,指令格式能将各种寄存器和存储器引用加上寻址方式予以组合

缺点:

  • 增加了CPU的复杂程度

指令集设计

指令集定义了处理器应完成的多数功能,对处理器的实现有着显著的影响,是程序员控制处理器的方式,设计时必须考虑程序员的要求

设计基本原则:

  • 完备性/完整性

    • 操作类型应当尽可能完备,但是太复杂也会给硬件实现增加困难
  • 兼容性

    • 应当兼容以前的指令系统,为软件重复利用带来方便
  • 均匀性

    • 应当能对多种类型的数据进行处理
  • 可扩充性

    • 操作码要预留一定的编码空间

设计的基本问题:

  • 操作指令表

  • 数据类型

  • 指令格式

  • 寄存器

  • 寻址方式

  • 下一条指令地址的确定

指令周期

简单指令周期

当且仅有当机器关闭,不可被恢复的错误发生或者程序指令停止了计算机时,程序执行才会停止,不然操作系统的执行是不会停止的

指令周期:处理单个指令的过程

  1. 取指周期:从内存中获取指令

  2. 执行周期:执行所提取的指令

指令执行过程- 掘金

指令周期状态图

  1. 从内存中取指令

  2. 解析指令获取操作码

  3. 获取操作数

含有中断的指令周期

  1. 开中断时响应中断(Interupt enable)

    • 每执行完成一次指令后要check有无中断并且进行处理
  2. 关中断的时候不响应中断

指令周期状态图

间址周期

指令的执行可能涉及一个或多个存储器中的操作数,它们都要求一次存储器访问

  • 使用间接寻址,还需要额外的存储器访问

间址周期:把简介地址的读取看成是一个额外的指令子周期

计算机组成原理

概述(感觉没什么要写的

约束是作用于表中字段上的规则,用于限制存储在表中的数据

目的:保证数据库中数据的正确、有效性和完整性

约束 描述 关键字
非空约束 限制该字段的数据不能为 null NOT NULL
唯一约束 保证该字段所有数据都是唯一、不重复的 UNIQUE
主键约束 主键是一行数据的唯一标识,要求非空且唯一 PRIMARY KEY
默认约束 存储数据时,如果未指定该字段的值,则用默认值 DEFAULT
检查约束 保证字段值满足一个条件 CHECK
外键约束 用来让两张表的数据之间建立联系,保证数据的一致性和完整性 FOREIGN KEY

外键约束

  1. 添加外键

    1
    2
    3
    4
    5
    CREATE TABLE 表名(
    字段名 数据类型;
    ...
    [CONSTRAINT] [外键名称] FOREIGN KEY (外键字段名) REFERENCES 主表 (主表列名)
    )
    1
    ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名) REFERENCES 主表 (主表列名)
  2. 删除外键

    1
    2
    ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;

删除/更新行为

行为 说明
NO ACTION 当在父表中删除/更新对应记录时,应检查该记录是否有对应外键,如果有则不允许删除/更新
RESTRICT 当在父表中删除/更新对应记录时,应检查该记录是否有对应外键,如果有则不允许删除/更新
CASCADE 当在父表中删除/更新对应记录时,应检查该记录是否有对应外键,如果有,则也删除/更新外键在子表中的记录
SET NULL 当在父表中删除对应记录时,应检查该记录是否有对应外键,如果有则设置子表中该外键值为null(要求外键允许取null)
SET DEFAULT 父表有变更时,自建将外键列设置成一个默认的值(innodb不支持)
1
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名) REFERENCES 主表 (主表列名) ON UPDATE [行为] ON DELETE [行为]

字符串函数

函数 功能
CONCAT(S1, S2, …, Sn) 字符串拼接
LOWER(str) 转小写
UPPER(str) 转大写
LPAD(str, n, pad) 用pad进行左填充,达到n个字符长度
RPAD(str, n, pad) 用pad进行右填充,达到n个字符长度
TRIM(str) 出去首部和尾部的空格
SUBSTRING(str, start, len) 截取字符串

数值函数

函数 功能
CEIL(x) 向上取整
FLOOR(x) 向下取整
MOD(x, y) 取模
RNAD() 0·1之间的随机数
ROUND(X, y) x四舍五入,保留y位

日期函数

函数 功能
CURDATE() 当前日期
CURTIME() 当前时间
NOW() 当前日期和时间
YEAR(date) 指定date的年份
MONTH(date) 指定date的月份
DAY(date) 指定date的日期
DATE_ADD(date, INTERVAL expr type) 一个日期/时间值 加上一个时间间隔expr
DATEDIFF(date1, date2) 相差的天数(date1 - date2)
  • DATE_ADD函数中的INTERVAL是固定要写的,type可以是DAY、MONTH、YEAR

流程函数

函数 功能
IF(value, t, f) 如果value为true则t,否则f
IFNULL(value1, value2) 如果value不为空则value1,否则value2
CASE WHEN [val1] THEN [res1] … ELSE [default] END 如果val1为true则res1,…,否则default默认值
CASE [expr] WHEN [val1] THEN [res1] … ELSE [default] END 如果expr等于val1则res1,…,否则default默认值
  • 多个目标要用多个when

概述

如何将更多任务装入主存

  • 增大主存容量

  • 使用交换技术、

    • 当主存中没有处于就绪的任务时,操作系统调入其他任务来执行

    • 分区和分页

  • 虚拟存储器

    • 请求分页:每次访问仅将当前需要的页面调入主存,而其他不活跃的页面放在外存磁盘上

    • 虚拟地址

分区方式

主存分为两大区域:系统区、用户区

  1. 简单固定分区

    用户区划分成长度不等的固定长的分区,当一个任务调入主存时,分配一个可用的、能容纳它的、最小的分区

  2. 可变长分区

    用户区按每个人物所需要的内存大小进行分配

    • 时间越长,存储器中的碎片就会越多

分页方式

基本思想:

  • 把主存分成固定长且比较小的存储块,称为页框,每个任务也被划分成固定长的程序块,称为

  • 将页装入页框上,且无需采用连续的页框来存放一个任务中所有的页

逻辑地址:指令中的地址

物理地址:实际主存地址

虚拟存储器

基本思想:

  • 请求分页:仅将当前需要的页面调入主存

    • 通过硬件将逻辑地址转换为物理地址

    • 未命中时在主存和硬盘之间交换信息

优点:

  1. 在不扩大物理内存的前提下,可以载入更多的任务

  2. 编写程序时不需要考虑可用物理内存的状态

  3. 可以在大于物理内存的逻辑地址空间中编程

流程

  1. 先把程序加载到硬盘的特定区域,然后我们什么时候需要这个内存,移动到主存中去

  2. 存储是否被加载到物理内存中,如果被加载进物理内存,则是物理地址,如果没有在里面就在磁盘中

    • 满了可以使用替换策略进行替换
  3. 内存中有的,硬盘中也是有的

    • 拷贝关系

页大小:4KB、8KB、$\cdots$

映射算法:全相联映射

写策略:写回法

  • 被替换出来才修改硬盘中的数据

种类

  • 分页式虚拟存储器

  • 分段式虚拟存储器

  • 段页式虚拟存储器

分页式虚拟存储器

主存储器和虚拟地址空间都被划分成大小相等的页面

  • 虚拟页/逻辑页:虚拟地址空间中的页面

  • 物理页/页框:主存空间中的页面

页表

页表中包含了所有虚拟页的信息,包括虚拟页的存放位置、有效位(有无被加载到物理内存中)、修改位、存取权限位等等

  • 保存在主存中

虚拟地址:页号+页内偏移量

页号 页内偏移量

根据页表中记录的物理页存放位置,可以将虚拟地址转化为物理地址

  • 虚拟页号 + 页内偏移量 $\rightarrow$ 物理页号 + 页内偏移量

  • location没写:指向硬盘的指针

  • loaction = null:表示磁盘里没有,而不是内存中没有

  • 虚拟页号比物理页号大一些

    • 虚拟页号没必要存储,按照相应的物理页号位置来找虚拟页号的位置

如果location的长度是不同的,那么必须按照最长的部分等长存储,以免无法进行更换

快表TLB

为了减少对内存的访问,我们将常用的页表的行放到Cache中去

  • 需要在前面加上个标记表示第几行

  • 映射方式:全相联映射、组相联映射

  • 替换策略:随机替换

流程

我们只要将虚拟页号根据页表转换到物理页号中去

  • 前提:在物理内存中

  • 如果hit,直接传入物理地址;如果miss,到页表中去访问

    • 这里的hit和miss发生在Cache中,因为TLB存放在Cache中

    • 如果hit并且是invaild(无效)的情况下,我们用硬盘把页送到内存中去,然后到Cache正常访问

      • 有效位是表示有无加载到物理内存中

如果没在物理内存中的话,就是发生了缺页操作,于是对磁盘进行操作

  • 也就是invaild操作

TLB、页表、Cache缺失组合

序号 TLB Cache 可能性 说明
1 hit hit hit 可能 TLB命中则页一定命中,信息在主存里,就可能在Cache中
2 hit hit miss 可能 TLB命中则页一定命中,信息在主存里,可能不在Cache中
3 miss hit hit 可能 TLB缺失但页可能命中,信息在主存里,就可能在Cache中
4 miss hit miss 可能 TLB缺失但页可能命中,信息在主存里,但可能不在Cache中
5 miss miss miss 可能 TLB缺失,则页也可能缺失,信息不在主存,一定也不在Cache
6 hit miss miss 不可能 页缺失,说明信息不在主存,TLB一定没有该页表项
7 hit miss hit 不可能 页缺失,说明信息不在主存,TLB一定没有该页表项
8 miss miss hit 不可能 页缺失,说明信息不在主存,Cache一定没有该信息
  • Cache是内存的拷贝

  • TLB miss的情况下只是比hit的情况多一次内存访问

访问主存和硬盘次数

  • 无需访问主存:1

  • 访问一次主存:2、3

  • 访问两次主存:4

  • 访问2次主存,且访问硬盘:5

分段式虚拟存储器

将程序和数据分成不同长度的段,将所需的段加载到主存中

虚拟地址:段号 + 段内偏移量

优点:段的分解与程序的自然分解相对应,易于变易、管理、修改和保护

缺点:段的长度不固定

段页式虚拟存储器

将程序和数据分段,段内再进行分页

  • 每个分段都有一个页表

虚拟地址:段号 + 页号 + 页内偏移量

优点:程序按段实现共享与保护

缺点:需要多次查表

概述

特性:

  • 用于不经常使用的、数据量较大的信息

  • 非易失性

类型:

  • 磁盘存储器

    • 软盘floppy disk

    • 硬盘hard disk

  • 光存储器

  • 磁带

  • U盘

  • 固态硬盘

硬磁盘存储器

结构

磁盘存储器每个盘片表面有一个读写磁头,所有磁头通过机械方式固定在一起,同时移动

  • 磁头对盘片进行读写操作

在任何时候,所有磁头都位于距离磁盘中心等距离的轨道上

  • 蓝色代表主轴

  • 红色代表磁盘

  • 绿色代表磁臂和磁头

读写机制

在读写操作期间,磁头静止,盘片在其下方进行旋转

  • 单磁头:读写共用

  • 双磁头:使用一个单独的磁头进行读取

数据组织

盘片上的数据组织呈现为一组同心圆环,称为磁道

数据以扇区的形式传输到磁盘或传出

  • 默认为512B

相邻磁道之间有间隙,相邻扇区之间也有

所有盘片上处于相同的相对位置的一组磁道称为柱面

扇区划分

  1. 恒定角速度

    保持读写速度恒定,能以磁道号和扇区号直接寻址各个数据块

  2. 多带式记录

    将盘面划分为多个同心圆区域,每个区域中各磁道的扇区数量时相同的,距离中心较远的分区包含的扇区数多于距离中心的分区

格式化

磁道必须有一些起始点和辨别每个扇区起点和终点的方法

格式化时会附有一些仅被磁盘驱动器使用而不被用户存取的额外数据

I/O访问时间

寻道时间:磁头定位到所需移动到的磁道花费的时间

  • 初始启动时间,跨越若干磁道所用的时间

旋转延迟:等待响应扇区的起始处到达磁头所需的时间

  • 通常是磁道旋转半周的时间

传送时间:数据传输所需的时间

  • 假设:T = 传送时间、b = 传送的字节数、N = 每磁道的字节数、r = 旋转速率(转/秒),那么$T = \frac{b}{rN}$

平均访问时间:$T_a = T_s + \frac{1}{2r} + \frac{b}{rN}$

  • $T_s$ 是平均寻道时间

对于连续访问多个相邻磁道时,对于每个磁道都要考虑旋转延迟,通常只需要考虑第一个磁道的寻道时间

  • 除非明确知道跨越一个磁道需要的时间

磁头寻道/磁盘调度

  1. 先来先服务FCFS

    按照请求访问磁盘的先后次序进行处理

  2. 最短寻道时间优先SSTF

    优先处理起始位置与当前磁头位置最接近的读写任务

    可能会出现饥饿现象,尤其是位于两端的磁道请求

  3. 扫描/电梯SCAN

    总是按照一个方向进行磁盘调度,直到该方向上的边缘,然后改变方向

  4. 循环扫描C-SCAN

    只有磁头朝某个方向移动时才会响应请求,移动到边缘后立即让磁头返回起点(0),返回途中不做任何处理

    • 从N跳到0
  5. LOOK

    只要磁头移动方向上不再有请求就立即改变磁头方向

  6. C-LOOK

    只要在磁头移动方向上不再有请求,就立即让磁头返回起点(不是0

光存储器

比如光盘(CD)、光盘只读存储器(CD-ROM)、可刻录光盘(CD-R)、可重写光盘(CD-RW)、数字多功能光盘(DVD)

CD和CD-ROM

CD-ROM更加耐用且有纠错功能

通过安装在光盘播放器或启动装置内的低强度激光束从CD或CD-ROM读取信息

  • 凹坑反射回低强度激光

  • 反射回高强度激光

盘片上包含一条单螺旋轨道,轨道上的所有扇区长度相同

优点:廉价地大规模复制,可更换

缺点:只读,存取时间长

磁带

使用与磁盘类似的记录和读取技术

读取:顺序读取

  • 磁盘是直接读取

U盘

采用了快闪存储器,属于非易失性半导体存储器,体积小容量大,携带方便

  • 固态硬盘容量更大,存储性能更好

冗余磁盘阵列RAID

将多个独立操作的磁盘按某种方式组织成磁盘阵列,以增加容量

  • 将数据存储在多个盘体上,通过这些盘并行工作来提高数据传输率

采用数据冗余来进行错误恢复以提高系统可靠性

级别 种类 描述 磁盘要求 数据可用性 大I/O数据传输能力 小I/O请求速率
0 条带化 非冗余 N 比单盘低 很高 读和写都很高
1 镜像 镜像 2N 比RAID 2、3、4、5高,比6低 读比单盘高,写和单盘类似 读高达单盘的两倍,写和单盘类似
2 并行存取 海明码校验 N+m 比单盘高很多,与RAID 3、4、5差不多 列表各级中最高 接近单盘的两倍
3 并行存取 位交错奇偶校验 N+1 比单盘高很多,与RAID 2、4、5差不多 列表各级中最高 接近单盘的两倍
4 独立存取 块交错奇偶校验 N+1 比单盘高很多,与RAID 2、3、5差不多 读和RAID 0类似,写低于单盘 读与RAID 0类似,写显著低于单盘
5 独立存取 块交错奇偶校验 N+1 比单盘高很多,与RAID 2、3、4差不多 读和RAID 0类似,写低于单盘 读与RAID 0类似,写显著低于单盘
6 独立存取 块交错奇偶校验 N+2 列表各级中最高 读和RAID 0类似,写比RAID 5低 读与RAID 0类似,写显著低于RAID 5

RAID 0

数据以条带的形式在可用的磁盘上分布

不采用冗余来改善性能

  • 不是RAID家族的真正成员

用途:

  1. 高数据传输率

  2. 高速响应I/O请求

RAID 1

采用数据条带,简单备份所有数据来实现冗余

优点:

  1. 高速响应I/O请求

  2. 读请求可以选择寻道时间较小的那个

  3. 写请求可以并行完成,受限于写入较慢的磁盘

  • 需要更新两个对应的条带
  1. 恢复受损磁盘简单

用途:

只限于用在存储系统软件、数据和其他关键文件的驱动器中

RAID 2

采用并行存取技术,所有磁盘都参与每个I/O请求的执行

纠错(海明码):

  • 纠错能力强于RAID 2

访问:

  • 读取:获取请求的数据和对应的校验码

  • 写入:所有数据盘和校验盘都被访问

RAID 3

优点:

  • 能够获得非常高的数据传输率

    • 对于大量传送,性能改善特别明显

缺点:

  • 一次只能执行一个I/O请求

    • 面向多个I/O请求,性能将受损

RAID 4

采用独立存取技术,采用相对较大的数据条带,根据各个数据盘上的数据来逐位计算奇偶校验条带

性能:

  • 当执行较小规模的I/O写请求时,RAID 4会遭遇写损失

    • 每一次写操作,不仅要修改用户数据,而且要修改对应的校验位

RAID 5

与RAID 4组织方式相似,但在所有磁盘上都分布了奇偶校验条带

  • 避免潜在的I/O瓶颈问题

访问时需要两读两写

RAID 6

采用两种不同的校验码,并将校验码以分开的块存于不同的磁盘中

优点:

  • 提升数据可用性

缺点:

  • 写损失:每次都要影响到两个校验块

基础

存储器由一定数量的单元构成,每个单元可以被唯一标识,每个单元都有存储一个数值的能力

  • 地址:单元的唯一标识符

  • 地址空间:可唯一标识的单元总数

  • 寻址空间存储在每个单元中的信息的位数

    • 大多数存储器是字节寻址

存储器层次结构_存储系统的层次结构_亚撒西带师的博客-CSDN博客

半导体存储器

位元(memory cell):半导体存储器的基本元件,用于存储1位数据

  • 呈现两种稳态(或半稳态):分别表示二进制的0和1

  • 能够至少被写入数据一次:用来设置状态

  • 能够被读取来获取状态信息

半导体存储器类别:

类型 种类 可擦性 写机制 易失性
随机存取存储器(RAM) 读-写存储器 电可擦除,字节级 易失
只读存储器(ROM) 只读存储器 不可能 掩膜 非易失
可编程ROM(PROM) 只读存储器 不可能 非易失
可擦除PROM(EPROM) 主要进行读操作的存储器 紫外线可擦除,芯片级 非易失
电可擦除PROM(EEPROM) 主要进行读操作的存储器 电可擦除,字节级 非易失
快闪存储器 主要进行读操作的存储器 电可擦除,块级 非易失

随机存取存储器(RAM)

特性:

  • 可以简单快速地进行读/写操作

  • 易失的(Volatile)

类型:

  1. DRAM(动态RAM)

    在电容器上用电容充电的方式存储数据

    • 电容器有无电荷分别代表二进制1和0

      需要周期地充电刷新以维护数据存储

    • 电容器有漏电的自然趋势

    • 有一个阈值来确定电荷是解释为1还是0

    • 刷新是异步刷新

      传统DRAM是异步的

    1. 处理器向内存提供地址和控制信号,表示内存中特定单元的一组数据应该被读出或写入DRAM

    2. DRAM执行各种内部功能,如激活行和列地址线的高电容,读取数据,以及通过输出缓冲将数据输出,处理器只能等待这段延迟,即存取时间

    3. 延时后,DRAM才写入或读取数据

  2. SRAM(静态RAM)

    使用传统触发器、逻辑门配置来存储二进制值

    • 使用与处理器相同的逻辑元件

      只要有电源,就可以一直维持数据

DRAM和SRAM对比

相同

  • 易失性两者都要求电源持续供电才能保持位值

不同

  • DRAM具有更简单、更小的位元,但要求能支持刷新的电路

  • DRAM密度更高,价格更低

  • SRAM通常更快

  • DRAM倾向满足大容量存储器的需求,SRAM一般用于高速缓存,SRAM用于主存

高级DRAM架构

传统的DRAM芯片受到其内部架构与处理器内存总线接口的限制

类型:

  1. SDRAM(同步DRAM)

    SDRAM与处理器的数据交互同步与外部的时钟信号,并且以处理器/存储器总线的最高速度运行,不需要插入等待状态

    • 由于SDRAM随系统时钟及时移动数据,CPU直到数据何时准备好,控制器可以完成其他工作

    • 异步是需要再次沟通的,而同步是减少一些交互,确定具体的交互时间(延迟时间)

      数据读写是在时钟周期的上升点进行

  2. DDR SDRAM(双速率SDRAM)

    每个时钟周期发送两次数据,一次在时钟脉冲的上升沿,一次在下降沿

    DDR $\rightarrow$ DDR2 $\rightarrow$ DDR3 $\rightarrow$ DDR4

    • 增加操作频率

    • 增加预取缓冲区

只读存储器(ROM)

特性:

  • 非易失性:不要求供电来维持数据

  • 只可读:但不能写入新数据

应用:

  • 微程序设计、库子系统、系统程序、函数表

问题:

  • 无出错处理机会

  • 用户无法写入数据

    • 唯一的数据写入机会在出厂时完成

可编程ROM(PROM)

PROM提供了灵活性和方便性,在大批量生产领域仍具有吸引力

特性:

  • 非易失性

  • 只能写入一次

    • 写过程是用电信号执行

    • 需要特殊设备来完成写或“编程”过程

可擦除可编程“只读”存储器(EPROM)

EPROM比PROM更贵,但有可多次改写的优点

特性:

  • 光擦除:在写操作前将封装芯片暴露在紫外线下

    • 所有的存储单元都便会相同的初始状态

    • 每次擦除需要约20分钟

  • 电写入

电可擦除可编程“只读”存储器(EEPROM)

与EPROM对比,EEPROM更贵,且密度低,支持小容量芯片

特性:

  • 可以随时写入而不删除之前的内容

  • 只更新寻址到的一个或多个字节

  • 写操作每字节需要几百微秒

快闪存储器

价格和功能介于EPROM和EEPROM之间

特性:

  • 电可擦除

    • 与EEPROM相同
  • 擦除时间为几秒

    • 优于EPROM,不如EEPROM
  • 可以在块级擦除,不能在字节级擦除

    • 优于EPROM,不如EEPROM

从位元到主存

寻址单元

寻址单元由若干相同地址的位元组成

每个寻址单元内的数据不能进行局部修改,而是整体修改

寻址模式:

  • 字节(Byte):常用

  • 字(Word)

存储阵列

存储阵列由大量寻址单元组成

选中就是对行和列进行加电,然后同时被加电的地方被选中

随机访问:先读取地址,然后找到行和列,然后选中,所以无论是什么单元,都是一样的访问时间

如何寻址

地址译码器:

如何刷新

存储周期:读/写一次所耗费的时间

  • 某行刷新一次的时间也等于一个存取周期

刷新间隔:所有存储单元都刷新一遍的时间

刷新类型:

  1. 集中式刷新(Centralized refresh)

    停止读写操作,并刷新每一行

    • 刷新时无法操作内存
  2. 分散式刷新(Decentralized refresh)

    在每个存储周期中,当读写操作完成时进行刷新

    • 会增加每个存储周期的时间
  3. 异步刷新(Asynchronous refresh)

    每一行各自以64ms间隔刷新(按时间切割)

    • 效率高

芯片

芯片引脚:

  • Address:A0-A19

  • Data:D0-D7

  • Vcc:电源

  • Vss:地线

  • CE:芯片允许引脚

  • Vpp:程序电压

  • WE:写允许

  • OE:读允许

  • RAS:行地址选通

  • CAS:列地址选通

模块组织

  1. 位扩展

    地址线不变,数据线增加

    • 使用8个4K*1bit的芯片组成4K*8bit的存储器

  2. 字扩展

    地址线增加,数据线不变

    • 使用4个16K*8bit的芯片组成64K*8bit的存储器

  3. 字位扩展

    地址线增加,数据线增加

    使用8个16K*4bit的芯片组成64K*8bit的存储器

高速缓冲存储器Cache

CPU的速度比内存的速度块,且两者的差距不断扩大,导致出现内存墙

Cache的基本思路

在使用主存之余,添加一块小而快的Cache,存放主存中部分信息的副本

  • Cache位于CPU和主存之间,可以集成在CPU内部或作为主板上的一个模块

Cache运行流程

  1. 检查:当CPU试图访问主存中的某个字时,会首先检查这个字是否在Cache中

  2. 检查后分两种情况:

  • 命中hit:如果在Cache则把这个字传送给CPU

  • 未命中miss:如果不在Cache,则将主存中包含这个字固定大小的块读入Cache中,然后再从Cache传送该字给CPU

无论如何Cache都会首先访问Cache

Cache通过标记tags来标识其内容在主存中的对应位置

  • 将Cache中每一行的标记和目标地址的标记进行比较,如果有相同即为命中

局部性原理

定义:处理器频繁访问主存中相同位置或相邻存储位置的现象

类型:

  1. 时间局部性:在相对较短的时间周期内,重复访问特定的信息

    • 也就是相同位置的信息

      1
      2
      3
      4
      int factorial = 1;  
      for (int i = 2; i <= n; i++) {
      factorial = factorial * i;
      }
  2. 空间局部性:在相对较短的时间周期内,访问相邻存储位置的数据

    1
    2
    3
    for (int i = 0; i < num; i++) {
    score[i] = final[i] * 0.4 + midterm[i] * 3 + assign[i] * 0.2 + activity[i] * 0.1;
    }
    • 顺序局部性:线性排列并访问

由于时间局部性,将未命中的数据再返回给CPU的同时存放在Cache中,以便再次访问命中

由于空间局部性,将包含所访问的字的块存储到Cache中,以便在访问相邻数据时命中

搬一个块的时间要比一次次搬块内每个单元的时间要快,因此Cache能节省时间

平均访问时间

设P是命中率,$T_c$是Cache的访问时间,$T_m$是主存的访问时间

  • 使用Cache的平均访问时间:$T_a = p \times T_c + (1-P) \times (T_c + T_m) = T_c + (1 - P) \times T_m$

    • 命中率P越大,$T_c$越小,效果越好

    • 如果想要$T_a < T_m$,必须要求$P > \frac{T_c}{T_m}$

Cache容量

扩大Cache容量后果:

  • 增大命中率P

  • 增加Cache的开销和访问时间$T_c$

    • 随着块的增大,P增长会放缓,因为过大就不满足局部性原理

映射功能

实现主存块到Cache行的映射

映射方式的选择会影响Cache的组织结构

  • 直接映射

  • 全关联映射

  • 组关联映射

Cache和主存结构

  1. Cache

    • 一行:tag + 行 + 字

    • 一共m个块,也就是m行

    • tag是主存储器的一部分,用来识别当前储存的是哪一块

  2. 主存:字长,每一块(k字)

直接映射

将主存中的每个块映射到一个固定可用的Cache行中,适合大容量的Cache

  • $Cache行号 = 主存储器块号\: \% \:Cache行数$

主存储器地址:

标记 Cache行号 块内地址

标记:地址中最高的n位,区分映射到同一行的不同块

  • $n = log_2M - log_2C$

    • M为块数,C为Cache行数
  • 为了成本,要用尽可能少的位置存储tag

优点:简单、快速映射、快速检查

缺点:两个块被重复使用的话有可能出现抖动的现象

全关联映射

一个内存块可以装入Cache的任意一行,适合容量较小的Cache

主存储器地址:

标记(块号) 字(块内地址)

优点:避免抖动

缺点:实现起来比较复杂,搜索代价大,即检查的时候需要去访问Cache每一行

组关联映射

Cache分为若干组,每一组包含相同数量的行,每个主存块被映射到固定组的任意一行,面向不同容量的Cache做了折中

Cache 的映射方式 - 面向云技术架构 - 痴者工良

  • $Cache组号 = 主存块号\: \% \:组数$

K - 路组关联映射:K是每一组的行数

  • K=1则等价于直接映射

  • K=Cache行数则等价于全关联映射

主存储器地址:

标记 Cache组号 块内地址

标记:地址中最高的n位,区分映射到同一组的不同块

  • $n = log_2M - log_2S$

    • M为块数,C为组数

三种映射方式对比

关联度:一个主存块映射到Cache中可能存放的位置个数

  • 直接映射:1

  • 全关联映射:Cache行数

  • 全关联映射:每组的行数

关联度越低,则命中率越低、判断是否命中的时间越短、标记所占额外空间开销越小

替换算法

最近最少使用算法(LRU)

替换在Cache中最长时间未被访问的数据块

  • 可以设计一个USE位,未被访问则加1,被访问则置0,替换USE位最大的行

先进先出算法(FIFO)

替换在Cache中停留时间最长的数据块

最不经常使用算法(LFU)

替换Cache中被访问次数最少的数据块

  • 每行设置一个计数器

随机替换算法(Random)

随机替换Cache中的数据块

写策略

  • 如果没被修改,则该数据块可以直接被替换掉

  • 如果被修改,则在替换掉该数据块之前,必须将修改后的数据块写回到主存对应位置

缓存命中时写策略

  1. 写直达

    所有写操作同时对Cache和主存进行

    优点:确保主存中的数据总是和Cache中的数据一致

    缺点:产生大量的主存访问,减慢写操作

  2. 写回法

    先更新Cache中的数据,当Cache中某个数据块被替换,如果它被修改了,才被写回主存

    • 利用脏位使用位表示是否被修改

      优点:减少访问主存的次数

      缺点:部分主存数据可能不是最新的(未发生替换但需要读主存的场景)

缓存未命中写策略

  1. 写不分配

    直接将数据写入主存,无需读入Cache,通常搭配写直达

    优点:避免Cache和主存数据不一致

  2. 写分配

    将数据所在的块读入Cache后,在Cache中更新内容,通常搭配写回法

    优点:减少写内存次数

行大小

  • 随着行大小的逐步增大,Cache命中率会增加

    • 空间局部性
  • 行大小较大后,继续增加行大小,Cache命中率会下降

    • 频繁替换

行太小,行数太多反时间局部性

行太大,行数太少反空间局部性

Cache数目

一级

  • 将Cache与处理器置于同一芯片

  • 减少处理器在外部总线上的活动,从而减少了执行时间

多级

  • 当$L_1$未命中时,减少处理器对总线上DRAM或ROM的访问

  • 使用单独的数据路径,代替系统总线在$L_2$缓存和处理器之间传输数据,部分处理器将$L_2$ Cache结合到处理器芯片上

统一

  • 更高的命中率,在获取指令和数据的负载之间自动进行平衡

  • 只需设计和实现一个Cache

分立

  • 消除Cache在指令的取值/译码单元和执行单元之间的竞争,在任何基于指令的流水线的设计中都是重要的
0%