1.总线
1.1总线的基本概念
**是什么:**是信息传输的公共通道,是将信息以一个或者多个源部件传送到
一个或多个目的部件的一组传输线。
- 信息
信息在总线上代表不同类型的数据或控制信号,包括但不限于:
- 数据:实际需要传输和处理的数据,例如字节、字、双字等。
- 地址:用于标识存储单元或I/O设备的位置的地址信息。
- 控制信号:用于协调和管理总线上数据传输的信号,例如读/写信号、时钟信号、总线请求和总线许可信号等。
- 源部件
源部件(Source Component)是指发送信息的设备或部件。在计算机系统中,源部件可以是以下之一:
- 中央处理器(CPU):发送控制信号、数据和地址信息。
- 存储器(Memory):发送存储单元中的数据。
- 输入/输出设备(I/O Devices):发送输入的数据或传输输出的数据。
- 目的部件
目的部件(Destination Component)是指接收信息的设备或部件。在计算机系统中,目的部件可以是以下之一:
- 中央处理器(CPU):接收来自存储器或I/O设备的数据。
- 存储器(Memory):接收并存储来自CPU或I/O设备的数据。
- 输入/输出设备(I/O Devices):接收来自CPU或存储器的数据,并将其用于实际的输入/输出操作。
1.1.1分散连接和总线连接
-
计算机系统的五大部件之间的互连方式有两种,一种是各部件之间使用单独的连线,称为 分散连接;
-
另一种则是将各部件连到一组公共信息传输线上,称为 总线连接。
随着计算机应用领域的不断扩大,I/O 设备的种类和数量也越来越多,采用分散连接方式很难实现随时增添或减撤设备,而总线连接方式则可以解决这个问题
1.1.2总线的特点和组成
-
问题出现:
总线本质是一个导线,当多个部件连接到总线上时,如果两个或两个以上部件同时向总线发送信息(也就是电信号1或者0),就会导致信号冲突,传输无效。
-
特点:
1.分时:在某一时刻,只允许有一个部件向总线发送信息
2.共享:在某一时刻,多个部件可以同时从总线上接收相同的信息
-
组成:
总线实际上是由许多传输线或通路组成,每条线都可以通过电信号传递一位二进制代码;对于一串二进制代码,可以在一段时间内一位一位传输完成。多条传输线,则可以同时传输多位二进制代码。
有时候多条传输线不一定比一条传输线好,因为多条传输线会受到干扰使效率降低
1.1.3总线的分类
总线可以应用在各种场景,从不同角度可以有不同的分类方法。
-
按数据传送方式:
并行传输总线: 多条传输线,则可以同时传输多位二进制代码
**串行传输总线:**对于一串二进制代码,可以在一段时间内一位一位传输完成
-
按传输数据宽度:在并行传输总线中,又可按宽度分为 8 位、16 位、32 位、64 位等传输总线。
-
按使用范围:计算机总线、测控总线、网络通信总线 等。
而更加常用的一种分类方式,则是按连接部件的不同,可以分为三类:片内总线、系统总线 和 通信总线
1. 片内总线
片内总线是指芯片内部的总线,如在 CPU 芯片内部,寄存器与寄存器之间、寄存器与运算逻辑单元 ALU 之间,都是由片内总线连接的。
2. 系统总线
系统总线是指 CPU、主存、I/O 设备各大部件之间的 信息传输线。由于这些部件通常都安放在主板或各个插件板(插卡)上,故又称 板级总线或 板间总线。从物理上看,就是由许多导线直接印制在电路板上,延伸到各个部件。
在系统总线中,按系统总线传输信息的不同,又可分为三类:数据总线、地址总线 和 控制总线。
(1)数据总线
数据总线用来传输各功能部件之间的 数据信息,它是双向传输总线,其位数与机器字长、存储字长有关,一般为 8 位、16 位或 32 位。
数据总线的位数称为 数据总线宽度,它是衡量系统性能的一个重要参数。如果数据总线的宽度为 8 位,指令字长为 16 位,那么,CPU 在取指阶段必须两次访问主存。
(2)地址总线
地址总线主要用来指出数据总线上的源数据或目的数据在 主存存储单元的地址 或 I/O 设备的地址。
地址总线上的二进制码就是一个 地址,由 CPU 输出,单向传输。地址线的位数与存储单元的个数有关。
(3)控制总线
控制总线是用来发出各种 控制信号 的传输线。
由于数据总线、地址总线都是被挂在总线上的所有部件共享的,要使各部件能在不同时刻占有总线使用权,就需要依靠控制总线来完成分配和调度。
通常对任一控制线而言,它的传输是单向的。但对于控制总线总体来说,又可认为是双向的。例如,CPU 可以向主存、I/O 设备发出读/写控制信号,也可以接收外部设备发来的中断请求。
3. 通信总线
这类总线用于计算机系统之间,或计算机系统与其他系统(如控制仪表、移动通信等)之间的通信。
通信总线通常按传输方式分为两种:串行通信 和 并行通信。
- 串行通信:是指数据在单条 1 位宽的传输线上,一位一位地按顺序分时传送。
- 并行通信:是指数据在多条并行的 1 位宽传输线上,同时由源传送到目的地。
并行通信适宜于近距离的数据传输,通常小于30m;串行通信适宜于远距离传送,可以从几米达数千公里。通信总线的数据传输速率一般都与距离成反比。
1.1.4总线的结构
总线结构通常可以分为 单总线结构 和 多总线结构。
1. 单总线结构
单总线结构将 CPU、主存、I/O 设备(通过I/O接口)都挂在一组总线上,允许 I/O 设备之间、I/O 设备与 CPU之间或 I/O 设备与主存之间直接交换信息。
这种结构简单,也便于扩充,但所有的传送都通过这组共享总线,因此极易形成计算机系统的瓶颈。
2.双总线结构
双总线结构的特点是,将速度较低的 I/O 设备从单总线上分离出来,形成 主存总线 与 I/O总线 分开的结构。
3. 三总线结构
如果继续将速率不同的 I/O 设备进行分类,然后将它们连接到不同的通道上,就可以进一步提升计算机的效率。这样就发展出了三总线结构。
1.1.5总线的性能指标
1. 总线宽度
通常是指数据总线的根数,用 bit(位)表示,如 8 位、16 位、32 位、64 位(即 8 根、16 根、32 根、64 根数据总线)。
2. 总线带宽
总线带宽代表了总线的 数据传输速率,即单位时间内总线上传输数据的位数,通常用每秒传输信息的字节数来衡量,单位用 MBps(兆字节每秒)表示。
例如,总线工作频率为 33 MHz,总线宽度为 32 位,则总线带宽为
33 × ( 32 ÷ 8 ) = 132 M B p s 33 × (32 ÷ 8) = 132 \, MBps 33×(32÷8)=132MBps
3. 信号线数
地址总线、数据总线和控制总线三种总线数的总和。
4. 时钟同步/异步
总线上的数据与时钟同步工作的总线,称为 同步总线;与时钟不同步工作的总线称为 异步总线。
5. 总线复用
一条信号线上分时传送两种信号。
例如,通常地址总线与数据总线在物理上是分开的两种总线,地址总线传输地址码这时候数据总线可能闲置,数据总线传输数据信息这时候地址总线可能闲置。为了提高总线的利用率,可以让地址总线和数据总线共用一组物理线路,在这组物理线路上分时传输地址信号和数据信号,即为总线的多路复用。
6. 总线控制方式
包括突发工作、自动配置、仲裁方式、逻辑方式、计数方式等。
其中,突发传输方式也称为 猝发传输,指对于在主存中连续存放的数据,访问时只需要给出一个首地址,耗费一个时钟周期;然后每个数据传送各占一个时钟周期,不必再给出地址就可以传输多个连续的数据。这样就可以大大提升数据传输速率。
1.1.6 总线判优(总线仲裁)
总线上连接的各种设备,一些是对总线有控制权的,称为 主设备(主模块);另一类则对总线没有控制权,只能响应从主设备发来的命令,称为 从设备(从模块)。
总线上信息的传递都是由主设备发起的;当某个主设备需要占用总线向另一个设备发送信息时,首先需要发出 总线请求信号。如果多个主设备同时发出请求、希望占用总线,就需要一个专门的 总线控制器 来做出判断, 按照一定的优先级确定哪个主设备可以使用总线。这个过程就称为 总线判优,或者 总线仲裁。
总线判优的实现可以分为两种形式:
- 集中式:将控制逻辑集中在一处(比如 CPU 中);
- 分布式:将控制逻辑分散在与总线连接的各个部件或者设备上。
以集中式为例,常见的总线判优方式有以下三种。
1. 链式查询
顾名思义,链式查询的硬件连接方式就是将设备接口电路排成一条链,依次进行查询。原理跟中断判优的 ”链式排队器“ 类似。
上图中,控制总线中有 3 根线专门用于总线的控制:
- BS(Bus State,总线状态):为 1 时表示 ”总线忙“,即总线已被占用;为 0 时表示 ”总线空闲“;
- BR(Bus Request,总线请求):传递各设备接口电路发来的总线请求信号;
- BG(Bus Grant,总线同意):由总线控制器经过总线判优之后、发出的允许某个设备使用总线的信号。
BG 信号是按照链式排列顺序,串行地依次向下传递的。
I/O 设备 0 的优先级最高,因此 BG 先到达 I/O 接口 0。如果这时接口 0 有总线请求,那么 BG 就不再向下传递,并且发出 ”总线忙“ BS 信号,表示设备 0 获得了总线使用权。如果接口 0 没有总线请求,则 BG 信号继续传递至 I/O 接口 1,依次查询判断。
可见,链式查询中,设备距离总线控制器 越近,优先级就 越高。
这种方式实现简单,很容易实现扩展;但对电路故障很敏感,而且优先级低的设备可能很难获取总线使用权。
2. 计数器定时查询
计数器定时查询的基本思路是,为每个设备定一个 设备地址,总线控制器中设置一个 计数器,按照设备地址号依次计数;当计数器的值是某个设备的地址时,该设备的总线请求就可以被响应、从而获取总线的使用权。
跟链式查询相比,计数器定时查询增加了一组 设备地址线,省去了总线同意信号线 BG。
当总线控制部件接收到 BR 上的总线请求时,如果当前总线没有被占用(BS = 0),那么就让计数器开始计数;并通过设备地址线,发出一组地址信号。如果地址线选中的设备,发出了总线请求信号,那么就可以获得总线使用权,此时计数器停止计数。
- 如果我们设定计数器每次都从 ”0“ 开始计数,那么设备的优先级就是按照地址 0,1,2,… 依次排列;
- 如果我们每次停止计数后不清零 、而是继续循环计数,那就相当于所有设备可以轮流占用总线、优先级相同;
- 如果我们通过程序来设置计数器的初始值,还可以灵活改变优先级;
这种方式对电路故障没有那么敏感,不过增加了控制线的数量(设备地址线一般有多条),控制也比较复杂。
3. 独立请求方式
这种方式更加直接,每个设备独立发出总线请求;总线控制器内设置排队电路,根据优先级单独向每个设备发送总线同意信号。
上图中,每个设备都有一对总线请求线 BRi 和总线同意线 BGi 。当某个设备要使用总线时,就通过自己的请求线发出请求信号;总线控制器通过内部的排队电路进行判优,决定响应哪一个设备的请求,发出对应的同意信号。
这种方式响应速度快,优先次序也可以通过程序设置灵活改变,但控制线数量更多、总线控制更加复杂。
对于 n 个设备的系统,要确定总线使用权属于哪个设备,链式查询只用了 2 条线(BR、BG);计数器定时查询则需要进行设备编址,大致需要 log2 n 条设备地址线和 1 条 BR 线;而独立请求方式则需要 2n 条线。
1.1.7 总线事务和总线周期
从一个设备发出总线请求、获取到总线使用权,到使用完成、将总线释放,这个完整的过程就是一次 总线操作,一般称为 总线事务。完成一次总线事务的时间,就称为 总线周期。
总线事务中包括一些具体操作,对应着总线周期中的不同阶段:
- 申请分配阶段:主设备发出 总线请求,经过总线控制器中总线仲裁机构的 判优,决定将总线使用权交给某个设备(申请者);
- 寻址阶段:取得使用权的主设备,通过总线发出要访问的从设备地址和有关命令,启动从设备;
- 传输阶段:主设备和从设备进行数据交换,数据从源模块发出,经数据总线流入目的模块;
- 结束阶段:系统总线上撤除主设备的有关信息,让出总线的使用权。
1.1.8 总线通信控制(总线定时)
在总线周期中,核心阶段是数据的传输。由于涉及到两个不同模块,因此双方在交换数据时什么时候传输开始、什么时候传输结束,以及如何进行协调配合,应该有一个统一的规则。这被称为 总线通信控制;因为主要涉及的是时间上的控制协调,所以也叫 总线定时。
总线通信控制通常有四种方式:同步通信、异步通信、半同步通信 和 分离式通信。
1. 同步通信
通信双方由统一时钟信号来控制数据传送,这种方式称为 同步通信。
时钟信号通常由 CPU 的总线控制部件发出,送到总线上的所有部件;也可以由每个部件各自的时序发生器发出,但必须由总线控制部件发出的时钟信号对它们进行同步。
- 优点:规定明确、统一,模块间的配合简单一致;
- 缺点:主、从模块时间配合属于强制性“同步”,必须在限定时间内完成规定的要求;并且对所有从模块都用同一限时,这就势必造成,对各不相同速度的部件而言,必须按最慢速度的部件来设计公共时钟,严重影响总线的工作效率,也给设计带来了局限性,缺乏灵活性。
同步通信一般用于总线长度较短、各部件存取时间比较一致的场合。
2. 异步通信
异步通信则没有公共的时钟标准,不要求所有部件严格的统一操作时间,而是采用 应答方式(又称 握手方式),当主模块发出 请求(Request)信号时,一直等待从模块反馈回来 “响应”(Acknowledge)信号后,才开始通信。
异步通信克服了同步通信的缺点,允许各模块速度的不一致性,给设计者充分的灵活性和选择余地。但要求主、从模块之间增加两条应答线(握手交互信号线),而且控制逻辑更加复杂,数据传输率也不及同步传输。
异步通信的应答方式,又可分为 不互锁、半互锁 和 全互锁 三种类型。
(1)不互锁方式
主设备发出请求信号后,不必等待接到从设备的响应信号,而是经过一段时间便撤销其请求信号;从设备接到请求信号后,发出响应信号,并且经过一段时间自动撤销响应信号。
可见通信双方完全独立,没有互锁关系。
(2)半互锁方式
主设备发出请求信号,必须等接到从设备的响应信号后,再撤销其请求信号,因此有互锁关系;
而从设备在接到请求信号后,发出响应信号,但不必等待主设备撤销请求信号,而是隔一段时间后自动撤销其响应信号:这两者之间没有互锁关系。
因此这种方式称为 半互锁方式。
(3)全互锁方式
主设备发出请求信号,必须等从设备回答后,再撤销其请求信号;
同样,从设备发出回答信号,必须等主设备撤销请求信号后,再撤销其回答信号。
双方存在互锁关系,所以称为 全互锁方式。
3. 半同步通信
半同步通信是同步通信和异步通信的结合。
半同步通信既保留了同步通信的基本特点,如所有的地址、命令、数据信号的发出时间,都严格参照系统时钟的某个前沿开始,而接收方都采用系统时钟后沿时刻来进行判断识别;同时又像异步通信那样,允许不同速度的模块和谐地工作,为此需要增设一条 “等待”(WAIT)响应信号线。
4. 分离式通信
分离式通信的基本思想是,将一个传输周期(或者总线周期)分解为两个子周期。
在第一个子周期,主设备 A 获取总线使用权后,将命令、地址及其它有关信息都发到系统总线上,经总线传输,由从设备 B 接收下来。这些信息的传输只占很短的时间,发送完后 A 立即放弃总线使用权,交给其它模块使用。
在第二个子周期,设备 B 接收到了 A 发来的所有信息,经过一系列内部操作,将 A 需要的数据准备好;此时便由 B 重新申请总线使用权,获准之后再进行数据传输。
这样,节省了等待 B 准备数据的时间,两个子周期中总线上都只有单向的信息流,两个设备都成为了主设备。
2. I/O 系统概述
在计算机中,除 CPU 和主存两大模块之外,第三个重要部分就是 输入输出模块,也叫做 输入输出系统,简写为 I/O 系统。
是什么:
是计算机系统中的一个重要组成部分,用于管理和协调计算机与外部设备之间的数据交换。I/O 系统包括硬件设备、软件程序和接口,负责处理输入设备的数据输入和输出设备的数据输出。
2.1 I/O 系统的发展
I/O 系统的结构,从简单到复杂,发展主要经历了四个阶段。
1. 早期阶段
早期的输入输出设备比较少,计算机的结构是以 CPU 为中心的分散连接方式;所有 I/O 设备都直接连接到 CPU ,与主存交换数据必须通过 CPU。
这样,每个 I/O 设备都必须配备一套独立的逻辑电路与 CPU 连接,线路复杂、难以维护和扩展;而且输入输出数据会打断 CPU 运行,效率比较低。
2. 接口模块和 DMA 阶段
之后计算机的连接方式发展出了总线结构,I/O 设备通过接口模块与总线相连,通过总线进行数据传输。
通常,在接口模块中都会设有 数据通路 和 控制通路。数据可以通过接口起到缓冲作用,也可以完成串并转换;控制通路则可以传送 CPU 发来的控制命令,或者向 CPU 发送来自 I/O 设备的反馈信号。许多接口还可以满足中断请求处理的要求,使 I/O 设备和 CPU 可以并行工作。
为了进一步提高 CPU 的效率,又出现了 直接存储器存取(Direct Memory Access,DMA)技术。在 I/O 设备和主存之间增加一条专门的数据通路,让它们可以直接交换信息,而无需经过 CPU。
在现代的小型或微型计算机中,一般都会采用接口模块和 DMA 的接口来实现 I/O 设备和主存的数据交换。
3. 通道结构阶段
对于大中型计算机,I/O 设备数量庞大、数据传输非常频繁,采用 DMA 方式需要为每个设备都配置专用的 DMA 接口,CPU 也需要对众多的 DMA 接口进行管理;控制非常复杂、工作效率也会受到很大影响。
因此在大中型计算机中,采用 I/O 通道 的方式来进行数据交换。
通道 可以看作一种从属于 CPU 的专用处理器,专门负责管理 I/O 设备,实现主存和 I/O 设备之间的数据交换。采用通道结构的计算机,I/O 设备的数据传输就全部交给通道来处理,提高了 CPU 的资源利用率。
4. 处理机阶段
I/O 系统进一步发展,出现了 I/O 处理机。I/O 处理机基本独立于主机工作,又称为 外围处理机。 具有 I/O 处理机的 I/O 系统与 CPU 的并行性更高,进一步解放了 CPU ,提升了 CPU 的工作效率。
2.2 I/O 系统的组成
I/O 系统主要由两部分组成: I/O 软件 和 I/O 硬件。
1. I/O 软件
I/O 系统软件的主要功能包括:
- 将用户编写的程序输入主机;
- 将运算结果传送给用户;
- 协调 I/O 系统和主机的工作。
不同结构的 I/O 系统采用的软件技术不同。
生活中常见的计算机一般采用接口模块方式,指令系统中需要设置专门的 I/O 指令;调用 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 设备的状态(”忙“ 还是 ”准备就绪“),来确定接下来是否可以进行数据交换;
- 形成具体的操作命令。例如磁盘驱动器的磁头读扇区、写扇区、寻找磁道等等。
(2)通道指令
通道指令是具有通道的 I/O 系统专门设置的指令,又称为 通道控制字(Channel Control Word,CCW),是通道用来执行 I/O 操作的指令。
这类指令位数一般会比较多,主要功能有:
- 指明要交换的一组数据在主存中的首地址;
- 指明要传送数据的字节数,或者在主存中的末地址;
- 指明所选设备的设备码,以及要完成的具体操作的命令码。
对于采用了通道结构的计算机,CPU 执行的 I/O 指令就只负责启、停 I/O 设备,查询通道和设备状态以及对通道进行操作控制;而具体的数据传输则交给通道来完成。
2. I/O 硬件
I/O 系统的硬件组成是多种多样的,不同结构的 I/O 系统硬件组成也会有所不同。
-
采用接口模块结构的 I/O 系统,硬件主要包括 接口模块 和 I/O 设备 两大部分。I/O 设备通过接口连接到主机;
-
采用通道或处理机结构的 I/O 系统,硬件主要包括 通道/处理机 、设备控制器 和 I/O 设备;一个通道/处理机可以和多个设备控制器相连,一个设备控制器又可以控制多台同类型的设备。
此外,连接各模块的数据通路(I/O 总线)也是 I/O 硬件的一部分。
2.3 I/O 设备
计算机硬件系统中,主要由三部分组成:CPU 、主存储器和输入输出设备。输入输出设备和它们对应的接口模块,就构成了输入输出系统。
CPU 与主存合称 主机,主机之外的大部分硬件设备都可以称为 I/O 设备,统称为 外部设备,简称 外设。
1. I/O 设备分类
从应用场景和功能上看,I/O 设备可以分为三大类:
(1)人机交互设备
实现用户(操作者)和计算机之间信息交流的设备,又可以分为两类:
- 输入设备:将人们熟悉的信息形式转换为机器能识别的信息形式,如键盘、鼠标、摄像头等。
- 输出设备:将机器运算结果转换为人们熟悉的信息形式,如打印机、显示器等。
(2)信息存储设备
系统软件和各种有用信息,都需要进行存储保留,这就需要能够持久化保存的外部存储设备。这类存储设备一般可以作为计算机的辅助存储器,比如磁盘、光盘、固态硬盘等。
(3)机-机通信设备
多台计算机之间、或者是计算机和其它系统之间如果需要进行通信,必须借助专门的通信设备。比如调制解调器(Modem),A/D、D/A 转换设备等。
2. I/O 设备的组成
I/O 设备的基本组成如下:
- 设备控制器用来控制 I/O 设备的具体动作,不同的 I/O 设备需要完成的控制功能也不同;
- 机、电、磁、光部件是 I/O 设备的工作部件,与具体功能有关;内部结构涉及到机、电、磁、光工作原理;
- 现代 I/O 设备一般还会通过 I/O 接口与主机相连。
2.4 I/O 接口(I/O 控制器)
两个系统或两个部件之间的交接部分,一般就称为 接口。接口可以是硬件上两种设备间的连接电路;也可以是两个软件之间交互的逻辑边界。
主机与 I/O 设备之间,专门设置一套硬件电路、配合相应的软件控制,实现两者间的信息交互,这就是 I/O 接口。不同的 I/O 设备都有其相应的设备控制器,而它们往往都是通过 I/O 接口与主机取得联系的。
2.4.1 I/O 接口的功能
I/O 接口主要的功能如下:
- 选址功能:根据 I/O 指令中的设备码进行设备选择;
- 数据缓冲:I/O 设备速度不一,与 CPU 相差比较大,需要进行数据的缓冲达到速度匹配、防止丢失数据;
- 串并转换:有些 I/O 设备采用串行传输方式,而 CPU 一般为并行传输,需要进行数据格式转换;
- 电平转换:I/O 设备的输入输出电平可能与 CPU 不同,需要进行电平转换;
- 传送控制命令:CPU 会向 I/O 设备发出各种控制信号,需要相应的传输通路;
- 反馈状态信息:I/O 设备需要将工作状态(比如 “忙” “准备就绪” “错误” “中断请求” 等)报告给 CPU,并且可能需要将状态信息进行保存,供 CPU 查询。
2.4.2 I/O 接口的基本结构
总线结构的计算机中,每一台 I/O 设备都是通过 I/O 接口挂到 I/O 总线上的。
1. 总线连接的数据通路
由于需要实现设备选择、数据缓冲、传送命令和状态等功能,总线中必须有相应的数据通路:
上图中的 I/O 总线,就包含了 数据线、设备选择线、命令线 和 状态线。
- 数据线
数据线是 I/O 设备与主机之间传送数据的线路。
数据线的根数一般等于存储字长的位数,通常是 双向的。若采用单向数据总线,则必须用两组才能实现数据的输入和输出功能,而双向数据总线只需一组即可。
- 设备选择线
设备选择线用来传送设备码,如果把设备码看做是地址号,那么设备选择线又可称为 地址线。
设备选择线的根数取决于 I/O 指令中设备码的位数,决定了能够连接设备的数量。设备选择线一般是一组,也可以有两组,其中一组用于主机向 I/O 设备发送设备码,另一组用于 I/O 设备向主机回送设备码。
- 命令线
命令线主要用来传输 CPU 向设备发出的各种命令信号,比如启动、清除、屏蔽、读、写等。
命令线是一组单向总线,根数与命令信号的数量有关。
- 状态线
状态线主要用来向主机报告 I/O 设备的状态信号,比如设备是否准备就绪、是否向 CPU 发出中断请求等。
状态线也是一组单向总线。
2. I/O 接口的基本组成
根据 I/O 接口的功能,以及总线结构中整体的数据通路,就可以推出接口应该具有的硬件配置。
(1)选址功能
设备码通过设备选择线(地址线)送至所有设备的接口,因此需要每个接口都必须具有选址功能。
当设备选择线上的设备码与本设备码相符时,发出一个 设备选中信号 SEL,这种功能可通过接口内的设备选择电路来实现。
(2)传送命令的功能
当 CPU 向 I/O 设备发出命令时,要求 I/O 设备能做出响应,因此通常在 I/O 接口中设有存放命令的 命令寄存器 以及 命令译码器。
命令寄存器用来存放 I/O 指令中的命令码,它受设备选中信号 SEL 控制。命令线和所有接口电路的命令寄存器相连,只有被选中设备的 SEL 信号有效,才会将命令线上的命令码存入命令寄存器。
(3)传送数据的功能
接口处于主机与I/O设备之间,因此主机与 I/O 设备之间进行数据传输必须经过接口。这就要求接口中具有数据通路,完成数据传送。这种数据通路还应具有 缓冲 能力,也就是能将数据暂存在接口内。
接口中通常设有 数据缓冲寄存器(Data Buffer Register,DBR),它用来暂存 I/O 设备与主机准备交换的信息,与 I/O 总线中的数据线是相连的。
(4)反映 I/O 设备工作状态的功能
为了使 CPU 能及时了解 I/O 设备的工作状态,接口内必须设置一些反映设备工作状态的触发器。
比如,可以用 完成触发器 D 和 工作触发器 B 来标志设备所处的状态。
- 当 D = 1,B = 0 时,表示 I/O 设备已经准备就绪;
- 当 D = 0,B = 1 时,表示 I/O 设备正处于工作状态;
- 当 D = 0,B = 0 时,表示 I/O 设备处于暂停状态。
由于现代计算机系统中大多采用中断技术,因此接口电路中一般还设有 中断请求触发器 INTR,当为 “1” 时,表示该设备向 CPU 发出中断请求;
接口内还有 中断屏蔽触发器 MASK,它与中断请求触发器配合使用,完成设备的屏蔽功能。
所有的状态标志触发器都与I/O总线中的状态线相连。此外,不同的 I/O 设备的接口电路中还可根据需要增设一些其他状态标志触发器。
这样就可以得到 I/O 接口的基本组成:
目前大多数 I/O 设备所共用的电路都制作在一个芯片内,作为 通用接口芯片。另一些 I/O 设备专用的电路,制作在 I/O 设备的 设备控制器 中。
2.4.3 I/O 端口及其编址
需要注意区分 “接口” (Interface)和 “端口” (Port)的概念:
端口 指的是接口电路中的一些寄存器,这些寄存器用来存放数据信息、控制信息和状态信息,相应的端口就称为 数据端口、控制端口 和 状态端口。
CPU 执行 I/O 指令中的输入操作时,从端口读入信息;执行输出操作时,将寄存器(比如 ACC)的信息写入到端口中。这样,CPU 对 I/O 设备的操作,就可以转换为对 I/O 端口的操作。一些端口,再加上对应的控制逻辑,就组成了接口。
CPU 要想访问某个 I/O 端口,就需要对 I/O 端口进行统一编号,每个端口对应一个 端口地址。对 I/O 端口的编址,可以选择跟内存统一,也可以完全独立。
1. 统一编址
统一编址就是把 I/O 地址看作存储器地址的一部分,也就是把 I/O 端口当做存储器单元统一进行地址分配。也称为 存储器映射方式。
这样,CPU 访问 I/O 端口时就可以直接用访存指令,而不需要专门的 I/O 指令,CPU 控制 I/O 设备更加方便;而缺点是端口会占用内存地址空间,减少了主存容量。
2. 不统一编址
不统一编址就是 I/O 地址和存储器地址完全分开,两者都有自己独立的地址空间,所以又叫 独立编址。也称为 I/O 映射方式。
不统一编址时,CPU 访问一个地址时,就无法从地址码上进行区分;所以必须通过设置专门的 I/O 指令 来访问 I/O 端口。这样就不会占用主存地址空间,用专门的 I/O 指令编写程序也会更加清晰;缺点是让指令系统更加复杂,CPU 需要提供对内存和 I/O 设备的两套读/写控制信号,硬件成本也更高。
2.4.4 I/O 接口的类型
I/O 接口按不同的方式,可以有以下几种分类。
-
按数据传送方式:分为 并行接口 和 串行接口;
-
按功能选择的灵活性:分为 可编程接口 和 不可编程接口;
-
按通用性:分为 通用接口 和 专用接口;
-
按数据传送的控制方式:分为 程序型接口 和 DMA 型接口。
程序型接口用于连接速度较慢的 I/O 设备,如显示终端、键盘、打印机等;具体的控制方式包括 程序查询方式 和 程序中断方式。DMA 型接口用于连接高速 I/O 设备,如磁盘、磁带等;控制方式采用 DMA 方式。
2.5 I/O 设备与主机交换信息的方式
I/O 设备与主机交换信息时,对信息传送的控制方式一共有五种:程序查询方式、程序中断方式、直接存储器存取方式(DMA)、I/O 通道方式、I/O 处理机方式。
其中,前两种方式都是通过 CPU 中程序指令的执行来控制的。
2.5.1 程序查询方式
程序查询方式是由 CPU 通过程序不断查询 I/O 设备是否已做好准备,从而控制 I/O 设备与主机交换信息。
1. 程序查询基本流程
采用这种方式实现主机和 I/O 设备交换信息,要求 I/O 接口内设置一个 状态标记,用来反映 I/O 设备是否准备就绪。CPU 通过检测这个标记,就可以了解 I/O 设备的准备情况。
当 I/O 设备较多时,CPU 就需要按 I/O 设备在系统中的 优先级 进行逐级查询。
为了完成这个查询的流程,CPU 通常需要执行以下 3 条指令:
- 测试指令:用来查询 I/O 设备是否准备就绪;
- 传送指令:当 I/O 设备准备就绪时,执行数据的传送指令;
- 转移指令:如果 I/O 设备未准备就绪,应执行转移指令;转至测试指令,继续测试 I/O 设备的状态。
当执行一段程序,需要启动某个 I/O 设备进行数据交互时,就把查询流程插入到运行的程序中。具体的查询流程如下:
① 这种方式传送数据时要占用 CPU 中的寄存器,所以首先要将寄存器原内容保护起来;
② 传送的往往是一批数据,所以需要设置 I/O 设备与主机交换数据的计数值,用来控制数据量;
③ 设置要传送的数据在主存缓冲区的首地址;
④ CPU 启动 I/O 设备;
⑤ 将 I/O 接口中的设备状态标志取至 CPU 并测试 I/O 设备是否准备就绪。如果未准备就绪,则等待,直到准备就绪为止;当准备就绪时,接着可实现传送。
对输入而言,准备就绪意味着接口电路中的数据缓冲寄存器已装满欲传送的数据,称为 输入缓冲满,CPU 可以取走数据;对输出而言,准备就绪意味着接口电路中的数据已被设备取走,称为 输出缓冲空,这样 CPU 可以再次将数据送到接口,设备则可以再次从接口接收数据。
⑥ CPU 执行 I/O 指令,从 I/O 接口的数据缓冲寄存器中读出一个数据(输入),或者把一个数据写入 I/O 接口中的数据缓冲寄存器内(输出),同时将接口中的状态标志复位;
⑦ 修改主存地址;
⑧ 修改计数值,若原设置计数值为原码,则依次减 1;若原设置计数值为负数的补码,则依次加 1;
⑨ 判断计数值。若计数值不为 0,表示一批数据尚未传送完,重新启动外设继续传送;若计数值为 0,则表示一批数据已传送完毕;
⑩ 结束 I/O 传送,继续执行原程序。
只要一启动 I/O 设备,CPU 就不断地查询 I/O 设备的准备情况,这就会暂停原程序的执行。当 I/O 设备准备就绪后,就将数据逐个传送;直到数据全部传送结束,CPU 才重新回到原程序继续执行。
所以在程序查询方式下,CPU 和 I/O 设备是串行工作的,效率不高。
2.接口电路
3.接口工作过程
2.5.2程序中断方式
程序查询方式效率较低,主要原因就是 I/O 设备工作速度较慢,CPU 启动设备后,需要等待一段时间 I/O 设备才能准备就绪、开始信息交换;而 CPU 则耗费了大量时间进行状态查询。
如果 CPU 在启动 I/O 设备后,继续执行自身的原程序;等到 I/O 设备准备就绪后,主动向 CPU 发出请求再予以响应,就可以大大提升工作效率。这个请求就可以以 I/O 中断 的形式出现。
1. 程序中断基本流程
2. 接口电路
3. I/O 中断处理过程
2.5.3直接存储器存取(DMA)
1. DMA 的概念和特点
如果 I/O 设备能直接与主存交换信息而不占用 CPU,那么 CPU 的资源利用率就可以进一步提高,这种方式就被称为 直接存储器存取(Direct Memory Access,DMA)。
DMA 方式的特点是,I/O 设备与主存之间有一条直接数据通路。因此,I/O 设备可以与主存直接交换信息,而不需要调用中断服务程序。这样 ,CPU 就不必暂停现行程序、专门去为设备服务,省去了保护现场和恢复线程的过程;所以工作效率比程序中断方式更高。
2. DMA 与 CPU 的访存冲突
3. DMA 接口的功能
4. DMA 接口的组成
5. DMA 的工作过程
6. DMA 方式和程序中断方式的对比
3.数据表示与运算
3.1进位计数制及其相互转换
书写时,可在十六进制数后面加上“H”,如17DBH 或(17DB)16;八进制数后面加上“O”,如372O或(372)8;若在数的后面加上“B”,如10101100B,即表示此数为二进制数,或写成(10101100)2。
十进制数、二进制数、八进制数、十六进制数对照表
十进制数 | 二进制数 | 八进制数 | 十六进制数 | 十进制数 | 二进制数 | 八进制数 | 十六进制数 |
---|---|---|---|---|---|---|---|
0 | 00000 | 0 | 0 | 16 | 10000 | 20 | 10 |
1 | 00001 | 1 | 1 | 17 | 10001 | 21 | 11 |
2 | 00010 | 2 | 2 | 18 | 10010 | 22 | 12 |
3 | 00011 | 3 | 3 | 19 | 10011 | 23 | 13 |
4 | 00100 | 4 | 4 | 20 | 10100 | 24 | 14 |
5 | 00101 | 5 | 5 | 21 | 10101 | 25 | 15 |
6 | 00110 | 6 | 6 | 22 | 10110 | 26 | 16 |
7 | 00111 | 7 | 7 | 23 | 10111 | 27 | 17 |
8 | 01000 | 10 | 8 | 24 | 11000 | 30 | 18 |
9 | 01001 | 11 | 9 | 25 | 11001 | 31 | 19 |
10 | 01010 | 12 | A | 26 | 11010 | 32 | 1A |
11 | 01011 | 13 | B | 27 | 11011 | 33 | 1B |
12 | 01100 | 14 | C | 28 | 11100 | 34 | 1C |
13 | 01101 | 15 | D | 29 | 11101 | 35 | 1D |
14 | 01110 | 16 | E | 30 | 11110 | 36 | 1E |
15 | 01111 | 17 | F | 31 | 11111 | 37 | 1F |
计算机系统为什么要采用二进制?
- 使用有两个稳定状态的物理器件就可以表示二进制数的每一位,制造成本比较低。
- 二进制的1和0正好与逻辑值“真”和“假”对应,为计算机实现逻辑运算提供了便利。
- 二进制的编码和运算规则都很简单,通过逻辑门电路能方便地实现算术运算。
(1)二进制和八进制、十六进制间的转换
例如,将二进制数1110011101.0010111转换为八进制数为:
左侧补0 分界点 右侧补0
↓ ↓ ↓
001 110 011 101 . 001 011 100
1 6 3 5 . 1 3 4
所以 (1110011101.0010111)2 = (1635.134)8 ;
同样道理,转换为十六进制数为:
0011 1001 1101 . 0010 1110
3 9 D . 2 E
所以 (1110011101.0010111)2 = (39D.2E)16 ;
- 二进制转换为八进制:每数三位就转换成对应的八进制数,位数不够则补0。
- 二进制转换为十六进制:每数四位就转换成对应的十六进制数,位数不够则补0。
- 八进制转换为二进制:每位都转换成对应的3位二进制数。
- 十六进制转换为二进制:每位都转换成对应的4位二进制数。
(2)任意进制数转换为十进制数
任意进制数的各位数码与它的权值相乘,再把乘积相加,即得到相应的十进制数。这种转换方式称为 按权展开法。
例如,将二进制数 11011.101 转换为十进制数为:
(11011.101)2 = 1 × 24 + 1 × 23 + 0 × 22 + 1 × 21 + 1 × 20 + 1 × 2-1 + 0 × 2-2 + 1 × 2-3
= 27.625
(3)十进制数转换为二进制数
先把十进制转换成二进制,然后再转换成八进制或者十六进制的时候就用第一种方法就行
将十进制数转换为二进制数,一般采用 基数乘除法。整数部分和小数部分分别处理,最后将整数部 分与小数部分的转换结果拼接起来。
-
整数部分的转换规则:除2取余,最先取得的余数为数的最低位,最后取得的余数为数的最高位,商为0时结束。 (即除2取余,先余为低,后余为高)
-
小数部分的转换规则:乘2取整,最先取得的整数为数的最高位,最后取得的整数为数的最低位,乘积为0或精度满足要求时结束。(即乘2取整,先整为高,后整为低)
例如,将十进制数 123.6875 转换为二进制数。
整数部分:
除2得商 余数
2 |123 … 1 最低位
2 |61 … 1
2 |30 … 0
2 |15 … 1
2 |7 … 1
2 |3 … 1
2 |1 … 1 最高位
2 |0
所以 (123)10 = (1111011)2
小数部分:
乘积取小数 乘2得积 取整数部分
0.6875 × 2 = 1.375 1 最高位
0.375 × 2 = 0.75 0
0.75 × 2 = 1.5 1
0.5 × 2 = 1 1 最低位
所以 (0.6875)10 = (0.1011)2
综合整数和小数部分,得到 (123.6875)10 = (1111011.1011)2
3.2 真值和机器数
在计算机中,如果不加特别的定义,用二进制存储的数都是非负数,不需要加正负号,也就是“无符号数”。
对有符号数而言,符号的“正”、“负”机器本身是无法识别的;不过由于“正”、“负”恰好是两种截然不同的状态,我们可以用“0”表示“正”,用“1”表示“负”,这样符号也被数字化了,并且规定将它放在有效数字的前面,即组成了有符号数。
例如,一个有符号的小数:
+ 0.1011 在机器中表示为 0 1 0 1 1
- 0.1011 在机器中表示为 1 1 0 1 1
再比如,一个有符号的整数:
+ 1100 在机器中表示为 0 1 1 0 0
- 1100 在机器中表示为 1 1 1 0 0
**真值:**把带“+”或“-”符号的数称为真值,表示为正、负号加某进制数绝对值的形式
**机器数:**把符号“数字化”的数,通常用“0”表示“正”,用“1”表示“负”
真值与机器数的关系:
真值代表着我们想表达的数,这是唯一的,但是机器数他不是唯一的,他在计算机底层对应的机器数可以不唯一;例如,原码、补码等等
3.3定点数及其编码表示
在计算机中,小数点不用专门的器件表示,而是按约定的方式标出。根据小数点位置是否固定,可以分为两种方法表示小数点的存在,即定点表示和浮点表示。
在现代计算机中,通常用定点补码整数表示整数,用定点原码小数表示浮点数的尾数部分,用移码表示浮点数的阶码部分。
**定点数:**小数点固定在某一位置的数为定点数,有以下两种格式。
**纯小数:**当小数点位于数符和第一数值位之间时,机器内的数为纯小数
**纯整数:**当小数点位于数值位之后时,机器内的数为纯整数
采用定点数的机器称为定点机。数值部分的位数n决定了定点机中数的表示范围
在定点机中,由于小数点的位置固定不变,故当机器处理的数不是纯小数或纯整数时,必须乘上一个比例因子,否则会产生“溢出”。
1. 无符号整数的表示
当一个编码的全部二进制位均为数值位时,相当于数的绝对值,该编码表示无符号整数。在字长相同的情况下,它能表示的最大数比带符号整数大。例如,8位无符号整数的表示范围为 0 ~ 28-1,也就是能表示的最大数为255;而8位带符号整数的最大数是127。通常,在全部是正数运算且不出现负值结果的情况下,使用无符号整数表示。例如,可用无符号整数进行地址运算,或用它来表示指针。
2. 带符号数的表示
最高位用来表示符号位,而不再表示数值位。
(1)定点整数
约定小数点在有效数值部分最低位之后。数据 x = x0x1x2…xn (其中 x0 为符号位,x1 ~ xn 是数值的有效部分,也称尾数),在计算机中的表示形式如图所示:
(2)定点小数
约定小数点在有效数值部分最高位之前。数据 x = x0.x1x2…xn(其中 x0 为符号位,x1~xn 是尾数,x1 是最高有效位),在计算中的表示形式如下图所示:
事实上,在计算机中,并没有小数点的表示,只是认为约定了小数点的位置:小数点在最右边的就是定点整数,在最左边的就是定点小数。它们原理相同,只是由于小数点位置不同而可以表示不同范围的数。我们这里重点只考虑定点整数就可以了。
3. 原码、补码、反码和移码
对于有符号的定点数,真实底层的机器数怎样表示,跟选择的编码方式有关。计算机中常用的编码方式有原码、补码、反码和移码。
- 原码表示法
用机器数的最高位表示数的符号,其余各位表示数的绝对值。纯小数的原码定义如下:
式子中 x 为真值,[ x ]原 表示原码机器数。
- 当真值为正的时候,真值转换为二进制后和机器数是一样的
- 当真值为负的时候,为1.XXXX的形式,即等于真值的绝对值加1
类似,纯整数的原码定义如下:
- 当真值为正的时候,真值跟机器数一样
- 当真值为负的时候,机器数的最高位是符号位即2的n次方,例如一共有5位二进制,那么最高位就是有效位即2的4次方,那么机器数就等于2的4次方加上真值的绝对值 ,例如真值是-12 求原码,则就是2的4次方加12等于28,计算出的是十进制,转化为二进制就可以
原码的性质:
-
由符号位与数的绝对值组成,符号位是0为正、1为负
-
简单直观,与真值的转换简单
-
0有 ±0 两个编码,即 [+0]原 = 00000 和 [-0]原 = 10000
例如,有8位的0101
那么无符号数是0255,一共256位,而有符号数可以表示的是-127127,相当于把无符号数可以表示的数砍半,即-127~-0和0到127,导致0有两种表示方法,从而浪费了一种编码形式
-
原码加减运算规则比较复杂,乘除运算规则简单
为了解决原码加减运算的复杂,从而又规定了另一种编码方式“补码”
- 补码表示法
纯整数的补码定义为:
这里 n 为整数的位数,真值 x 和补码机器数 [ x ]原 互为以 2n+1 为模的补数。如果字长为 n+1,那么补码的表示范围为 -2n ≤ x ≤ 2n - 1,比原码多表示了一个数 -2n。
例如:补码是10000000即128 那么代入公式 真值为 2的8次方(256) 减 补码(128)所以绝对值真值为128 打开绝对值后为-128
所以负数的补码和他的原码互补
在举一个例子:如1.11的补码,求其真值 我们知道小数点前是符号位不用改变 所以就是0.11取反加一变为0.01是原码 可以知道真值为0.25 又因为符号位是负的 所以真值是-0.25
变形补码是采用双符号位的补码表示法,其定义为
变形补码用于算术运算的ALU部件中,双符号位00表示正,11表示负,10和01表示溢出。
补码和真值的转换:
- 真值转为补码:对于正数, 与原码的转换方式一样;对于负数,符号位为1,其余各位由真值“取反加1”得到。
- 补码转为真值:若符号位为0,真值为正,跟原码的转换一样;若符号位为1,真值为负,其数值部分(绝对值)各位由补码“取反加1”得到。
- 反码表示法
负数的补码可采用“数值位各位取反,末位加1”的方法得到,如果数值位各位取反而末位不加1,那么就是负数的反码表示。正数的反码定义和相应的补码(或原码)表示相同。
反码表示存在以下几个方面的不足:0的表示不唯一(即存在±0);表示范围比补码少一个最小负 数。反码在计算机中很少使用,通常用作数码变换的中间表示形式。
原码、补码、反码三种编码表示总结如下:
-
三种编码的符号位相同,正数的机器码相同。
-
原码和反码的表示在数轴上对称,二者都存在 ±0 两个零。
-
补码的表示在数轴上不对称,0的表示唯一,补码比原码和反码多表示一个数。
-
负数的反码、补码末位相差1。
-
原码很容易判断大小。而负数的补码和反码很难直接判断大小,可采用这条规则快速判断:对于一个负数,数值部分越大,它的绝对值就越小,所以真值就越大(更靠近0)。
4.移码表示法
4.运算方法和运算电路
4.1基本运算部件
4.1.1运算器基本组成
运算器由算术逻辑单元(ALU)、累加器(AC)、状态寄存器(PSW)、通用寄存器组等组成。
- 算术逻辑单元:完成加、减、乘、除四则运算,与、或、非、异或等逻辑运算。
- 累加器:暂存参加运算的操作数和结果的部件,为 ALU 执行运算提供一个工作区。
- 状态寄存器:也称作标志寄存器,用来记录运算结果的状态信息。
- 通用寄存器组:保存参加运算的操作数和运算结果。
4.1.2逻辑门电路和逻辑运算(复习)
用半导体元器件可以构建出基本的逻辑门电路(与、或、非),能够表示基本的逻辑运算。
通过对与门、或门、非门的组合,可以构建出更加复杂的逻辑电路,进行各种复杂的组合逻辑运算。
逻辑运算中的“与”类似于算术中的乘法,“或”类似于算术中的加法,两者组合在一起时,与运算的优先级要更高。逻辑运算满足以下的规则:
重点:吸收律和反演律
4.1.3全加器
**全加器:**是用逻辑门电路实现两个二进制数相加并求出和的组合线路
一位全加器可以处理低位进位,并输出本位加法进位。多个一位全加器进行级联可以得到多位全加器。
一位全加器的真值表如下所示,其中 A 为被加数,B 为加数,相邻低位传来的进位数为 Cin,输出本位和为S,向相邻高位输出的进位数为 Cout 。
根据真值表,很容易写出一位全加器的输出表达式:
第一种结果可以用吸收律化简成第二种结果,但是由于S的结果有异或,所以Cout 选用有异或的结果 这样可以共用一个异或
所以,一位全加器可以利用两个异或门、两个与门和一个或门来实现:
4.1.4并行加法器
对于 n 位加法器,可以用 n 个全加器(实现两个本位数加上低位进位,生成一个本位和一个向高位的进位)串接起来实现逐位相加,位间进行串行传送,称为 串行进位加法器。
这样,一位全加器的输出表达式可以写为:
在串行进位链中,进位按串行方式传递,高位仅依赖低位进位,因此速度较慢。
为了提高加法器的速度,必须尽量避免进位之间的依赖。引入进位生成函数和进位传递函数,可以使各个进位并行产生,这种以并行进位方式实现的加法器称为 并行进位加法器。
在全加器的表达式中可以看到,进位信号 Ci 由两部分组成:
- AiBi 与低位无关,可以称为“本地进位”,记作 di;
- (Ai + Bi) Ci-1 与低位进位 Ci-1 有关,可以称为“传递进位”,系数 (Ai + Bi) 称作“传递系数”,记作 ti。
这样进位信号就可以简写为:
以 4 位并行加法器为例,串行进位链的进位表达式就可以写为:
如果我们将 C0 的表达式代入 C1,再依次迭代进 C2、C3 ,那么所有进位信号就只依赖于 C-1 了:
速记:本次进位 等于 有关系数(t) 乘以 上一进位的全部系数 在加上无关系数(d)
例子:如我们设计4位并行进位全加器逻辑电路
4.2定点数的移位运算
移位运算根据操作对象的不同,可以分为算术移位和逻辑移位。算术移位针对的是有符号数,逻辑移位针对的是机器码,可以看作无符号数。
1. 算术移位
算术移位的对象是有符号数,有符号数在计算机中采用补码表示。算术移位的特点是,移位后符号位保持不变;空出的位置根据正负和左右移位的情况,决定补 0 还是 1。
- 对于正数,由于 [ x ]原 = [ x ]补 = 真值,因此移位后的空位均补 0。
- 对于负数,算术左移时,有效高位移出,有效低位补 0;算术右移时,有效低位移出,有效高位补 1。
可见,不论是正数还是负数,移位后其符号位均不变。
例如,假设机器字长为 8,[4]补 = 0000 0100,[-4]补 = 1111 1100;
- 将 4 算术左移一位,就得到了 0000 1000 = [8]补;算术右移一位,就得到了 0000 0010 = [2]补;
- 将 -4 算术左移一位,就得到了 1111 1000 = [-8]补;算术右移一位,就得到了 1111 1110 = [-2]补;
- 切记只移动有效位,不动符号位
- 溢出判断
对于原码算术左移,符号位不变,高位移出,低位补“ 0 ”,当左移移出是数据位为“ 1 ”时,发生溢出。算术右移时,符号位不变,高位补“ 0 ”。
对于补码算术左移,符号位不变,高位移出,低位补“ 0 ”,当左移移出是数据位正数为“ 1 ”、负数为“ 0 ”时,发生溢出。算术右移时,符号位不变,高位补“ 1 ”。
2. 逻辑移位
逻辑移位不考虑符号位。
移位规则:逻辑左移时,高位移出,低位补 0;逻辑右移时,低位移岀,高位补 0 。
4.3定点数的加减运算
1. 补码的加减运算
补码加减运算的规则简单,易于实现。补码加减运算的公式如下(设机器字长为 n):
[A + B]补 = [A]补 + [B]补 (mod 2n)
[A - B]补 = [A]补 + [-B]补 (mod 2n)
注意:这里mod2的n次方 是因为符号位也参加运算 如果符号位相加进位后的最高位要舍弃
补码运算的特点如下:
- 按二进制运算规则运算,逢二进一。
- 如果做加法,两数的补码直接相加;如果做减法,则将被减数加上减数的机器负数。
- 符号位与数值位一起参与运算,加、减运算结果的符号位也在运算中直接得出。
- 最终将运算结果的高位丢弃,保留 n 位,运算结果也是补码。
例如,假设机器字长为 8 (n = 8),那么
[5]补 = 0000 0101,[4]补 = 0000 0100;
[-5]补 = 1111 1011,[-4]补 = 1111 1100;
[5 + 4]补 = 0000 0101 + 0000 0100 = 0000 1001 = [9]补;
[5 - 4]补 = [5 + (-4)]补 = 0000 0101 + 1111 1100 = 1 0000 0001 = [1]补;
[4 - 5]补 = [4 + (-5)]补 = 0000 0100 + 1111 1011 = 1111 1111 = [-1]补;
[-5 - 4]补 = [-5 + (-4)]补 = 1111 1011 + 1111 1100 = 1 1111 0111 = [-9]补;
这里的-9是真值,是补码取反加一得到10001001
也就是说[-9]补表示的是真值-9的补码
2.溢出判断方法
- 无符号数的判断
[5]补 = 0000 0101,[4]补 = 0000 0100;
[-5]补 = 1111 1011,[-4]补 = 1111 1100;
如果表示的是无符号数,那么:
[5 + 4]补 = 0000 0101 + 0000 0100 = [5]补 + [4]补 = 0000 1001 = [9]补; (加法不溢出)
[5 - 4]补 = 0000 0101 + 1111 1100 = [5]补 + [252]补 = 1 0000 0001 = [1]补; (加法溢出、减法不溢出)
[4 - 5]补 = 0000 0100 + 1111 1011 = [4]补 + [251]补= 1111 1111 = [255]补; (加法不溢出、减法溢出)
[-5 - 4]补 = 1111 1011 + 1111 1100 = [251]补 + [252]补 = 1 1111 0111 = [247]补; (加法溢出)
- 有符号数的判断
溢出 是指运算结果超出了数的表示范围。通常,大于能表示的最大正数称为正上溢,小于能表示的最小负数称为负上溢。仅当两个符号相同的数相加,或两个符号相异的数相减才可能产生溢出。
在之前的例子中,如果假设机器字长为 4(n = 4),能表示的有符号数范围为 -8 ~ 7,那么就有:
[5]补 = 0101,[4]补 = 0100;
[-5]补 = 1011,[-4]补 = 1100;
[5 + 4]补 = 0101 + 0100 = 1001 = [-7]补; (正溢出)
[5 - 4]补 = [5 + (-4)]补 = 0101 + 1100 = 1 0001 = [1]补;
[4 - 5]补 = [4 + (-5)]补 = 0100 + 1011 = 1111 = [-1]补;
[-5 - 4]补 = [-5 + (-4)]补 = 1011 + 1100 = 1 0111 = [7]补; (负溢出)
- 补码加减运算的溢出判断方法有以下 3 种:
(1)采用一位符号位。
由于减法运算在机器中是用加法器实现的,减法可以看作一个正数和一个负数的加法;因此无论是加法还是减法,只要参加操作的两个数符号相同,结果又与原操作数符号不同,就表示结果溢出。
比如上例中,一正一负相加必然不会溢出;两正数相加得到一个负数(符号位为1),则正溢出;两负数相加得到一个正数,则负溢出。
(2)采用双符号位。
运算结果的两个符号位相同,表示未溢出;运算结果的两个符号位不同,表示溢出,此时最高位就代表真正的符号。也就是说,符号位 S1S2 = 00 表示结果为正数,无溢出; S1S2 = 11 表示结果为负数,无溢出。 S1S2= 01 表示结果正溢出; S1S2 = 10 表示结果负溢出。溢出标志 OF = S1 ㊉ S2。
比如上例中,如果采用双符号位,机器字长就应该扩展为 5,那么:
[5]补 = 00 101,[4]补 = 00 100;
[-5]补 = 11 011,[-4]补 = 11 100;
[5 + 4]补 = 00 101 + 00 100 = 01 001 = [1]补; (正溢出)
[5 - 4]补 = [5 + (-4)]补 = 00 101 + 11 100 = 1 00 001 = [1]补;
[4 - 5]补 = [4 + (-5)]补 = 00 100 + 11 011 = 11 111 = [-1]补;
[-5 - 4]补 = [-5 + (-4)]补 = 11 011 + 11 100 = 1 10 111 = [-1]补; (负溢出)
4.4定点数的乘法运算
在计算机中,乘法运算由累加和右移操作实现。根据机器数的不同,可分为原码一位乘法和补码一位乘法。原码一位乘法的规则比补码一位乘法的规则简单。
1. 原码一位乘法
原码乘法运算的符号位与数值位分开计算。
- 确定乘积的符号位。由两个乘数的符号进行异或运算得到。
- 计算乘积的数值位。两个乘数的数值部分之积,可看作两个无符号数的乘积。
原码一位乘法的基本思路
类似小学竖式乘法的做法,让被乘数 x 分别乘以乘数 y 的每一位,然后再做叠加,每加一位都要移位,
正常来说整数是从高到低进行累加并且每加一次都要逻辑左移,这样可以会导致高位每次都要改变,
所以我们统一使用小数的方式进行累加和逻辑右移,这样可以保证高位只有一次改变,而计算出来的小数想要转化为整数移动小数点就可以
例如,当 x = 0.1101 = (0.8125)10,y = 0.1011 = (0.6875)10 时,计算 x · y。
符号位进行异或 得到符号位为0
最终的乘积,高位在“部分积”中,低位在“当前乘数”中,所以得到:
x · y = 0.1101 × 0.1011 = 0.10001111 = (0.55859375)10
2.补码一位乘法
补码一位乘法 是一种带符号数的乘法,采用相加/相减的校正操作,直接计算补码数据的乘积。
补码乘法是直接对补码进行的。对于纯整数,补码表达为:
而类似的,纯小数补码定义为:
为什么x为负时,补码表示为2+x?
我们知道为负时 纯小数补码为1.***的形式,又因为补码和她的原码互补
即x的补码 (1.0000) - x(-1.0000)= 2 所以x的补码 = 2 + x
① 被乘数 x 和乘数 y 符号均为正,
类似原码一位乘法,利用移位和加法的叠加,就可以计算出补码的乘积;这也就是最终计算结果的补码。
② 被乘数 x 为正,乘数 y 为负,
所以:
那么两数的乘积就可以写成:
这样一个计算结果,它的补码表示为:
可以看到,当乘数为负时,可以把乘数补码 [ y ]补 直接去掉符号位,当成一个正数与 [ x ]补 相乘;得到的结果再加上 [ -x ]补 进行校正。所以这种方法也叫做“校正法”。
例如,当 x = 0.1101 = (0.8125)10,y = 1.1011 = (-0.3125)10 时,计算 x · y。
我们可以直接计算 0.1101 × 0.1011 = 0.10001111,再加上 [ -x ]补 = 1. 0011,得到 :
0.10001111 + 1. 0011 = 1.10111111 = ( -0.25390625 )10
③ 被乘数 x 为负,乘数 y 为正
我们可以交换被乘数和乘数,直接按情况②来处理;也可以仔细分析,发现乘数 y 为正数,可以写成
[ y ]补 = 0. y1y2…yn 的形式,同样可以借鉴情况②中的分析和原码一位乘的方法。当两数的补码相乘时:
与原码一位乘完全类似,补码相乘也可以将乘数展开,逐位进行相乘、右移和叠加。不过需要注意的是,这时由于被乘数 x 是负数,右移时就需要在左侧高位补 1,也就是做算术右移、而不是逻辑右移。
例如,当 x = 1.1 = (-0.5)10,y = 0.011 = (0.375)10 时,计算 x · y。
最终的乘积,高位在“部分积”中,低位在“当前乘数”中,所以得到:
x · y = 1.1 × 0.011 = 1.1101 = ( - 0.1875 )10
④ 被乘数 x 和乘数 y 符号均为负
通过情况②和③的分析可以看出,当乘数 y 为正时,可以直接按照原码一位乘的方式进行补码乘法,注意需要进行算术右移;而当乘数 y 为负时,则可以先不考虑 y 的符号位,同样按照原码一位乘进行补码乘法,最后的结果要再加上 [ -x ]补 进行校正**,所以说4就是2和3的结合**
例如,当 x = 1.1 = (-0.5)10,y = 1.011 = (-0.625)10 时,计算 x · y。
我们可以直接计算 1.1 × 0.011 = 1.1101,再加上 [ -x ]补 = 0.1,得到 :
1.1101 + 0.1 = 1 0.0101 = ( 0.3125 )10
可以看出,如果使用双符号位来表示正负,会更加方便。
4.5定点数的除法运算
我们可以先从除法的竖式笔算入手,分析一下除法的具体步骤。
例如,当 x = (-0.1011)2 = (-0.6875)10,y = (0.1101)2 = (0.8125)10 时,计算 x / y。
首先可以看出,商的符号为负,余数的符号为负;其次利用竖式计算绝对值的商:
所以可以得到, x / y = - 0.1101(商)… - 0.00000111(余数) = (- 0.8125 … - 0.02734375 )10
分析:二进制只有1和0 也就是说 如果当前的被除数比除数大 那么商就为1 反则商位0 得到的余数补零后再作为下一轮的被除数进行计算 这个过程中除数每轮都要右移一位,如果被除数 x、除数 y 和商都是 4 位,就需要 8 位数据来保存余数,这就显得有些麻烦
更加简单的做法是,每轮相减除数不变,把余数左移n 轮计算完成之后,需要再右移 n 位,也就是乘以 2-n 才是真正的余数;所以跟乘法类似,除法运算在计算机中,是转换成逐位的“累加-左移”操作来实现的
1. 原码一位除法
原码一位除法和原码一位乘法一样,特点是符号位单独处理。商符由两个操作数的符号位做“异或”形成,减法操作用补码加法实现。
其中,0 . x1x2…xn 就是 x 的绝对值,记作 x* ;0 . y1y2…yn 是 y 的绝对值,记作 y* 。商符由两数符号位异或得到,商值由两数绝对值相除得到。
小数定点除法对被除数和除数有一定的约束条件:
0 <| 被除数 |≤| 除数 |
实现除法运算时,被除数应不大于除数,并且应该避免被除数和除数为 0。商的位数一般和操作数位数相同。
如果被除数大于除数,那么符号位就会改变
(1)恢复余数法
思路:是用“累加-左移”操作来实现的,先是被除数减去除数的绝对值 判断余数是正还是负,是正的话说明该位够除 那么商就可以上1 ,然后余数和商同时逻辑左移一位,再继续减去除数的绝对值 如果此时余数为负 那么说明该位不够除 那么上商0 然后要恢复到刚刚减去除数的绝对值的时候 ,那么就要加上除数的绝对值,这时候余数和商同时逻辑左移一位 开始下一位的判断 重复上面步骤 直到左移次数到达被除数的有效位数即可,这时上商次数比左移次数多一次
例如,当 x = (-0.1011)2 = (-0.6875)10,y = (-0.1101)2 = (-0.8125)10 时,计算 x / y。
首先看出,商的符号为正,余数的符号为负。并且得到:
x* = 0.1011,y* = 0.1101,[y*]补 = 0.1101,[-y*]补 = 1.0011
具体计算过程如下:
所以商值为 x* / y* = 0.1101;而余数由于经过了 4 次左移,所以最终还应该做 4 次右移才是真正的余数:0.0111 * 2-4 = 0.00000111,另外还要注意余数符号为负,所以最终结果为:
x / y = 0.1101(商)… - 0.00000111(余数)
由上例也可以发现,如果最终商保留 4 位,那么我们需要做 5 次上商,第一次上商其实是商的整数位;由于我们要求 |被除数| ≤ |除数|,因此正常情况下第一位商总是 0。所以对于小数除法而言,可以用它来做溢出判断:当该位为 1 时,表示当前除法溢出,不能进行;当该位为 0 时,当前除法合法,可以进行。
4.6浮点数的表示和运算
1.浮点数的表示
浮点数 就是小数点的位置可以浮动的数。例如:
365.242 = 3.65242 × 102
= 365242.0 × 10-3
= 0.365242 × 103
这其实就是”科学计数法“的思路。通常,浮点数被表示为下面的形式:
N
=
S
×
r
j
N = S \times r^j
N=S×rj
上式中,S 称作 尾数(可正可负),j 称作 阶码(可正可负),r 是 基数。在计算机中基数一般取 2,也可以取 4、8 或 16 等。
例如,一个二进制数 N = 11.0101,那么它可以写成各种不同的浮点形式:
N = 11.0101
= 1.10101 × 21
= 0.110101 × 210
= 11010.1 × 2-11
= 0.00110101 × 2100
…
为了提高数据精度,并且便于比较,在计算机中规定浮点数的尾数用 纯小数形式 表示。所以上面的 0.110101 × 210 和 0.00110101 × 2100 两种形式都可以在计算机中表示 N。不过很明显,后一种形式对有效数位是一种浪费,所以将尾数最高位为 1 的浮点数称为 规格化数。
这样,N 就有了唯一的规格化浮点形式:
N = 0.110101 × 210
浮点数表示为规格化形式,精度是最高的。
2.浮点数的表示格式
在计算机中,浮点数的格式如下图所示。采用这种数据格式的机器称为 浮点机。
浮点数由 阶码 j 和 尾数 S 两部分组成。
- 阶码是纯整数,阶符和阶码值合起来决定了小数点的实际位置;阶码值的位数 m 再结合阶符,可以反映浮点数的表示范围。
- 尾数是纯小数,数符 Sf 代表了浮点数的正负,而尾数值则是有效数位,位数 n 反映了浮点数的精度。
3.浮点数的表示范围
4. 浮点数的规格化
由于规格化数的精度最高,所以当一个非零的浮点数不是规格化数时,应该通过左右移动尾数、并同时修改阶码的方法,将它转换为规格化数。把一个非规格化数转换成规格化数的过程,叫做 规格化。
规格化可以分为 “左规” 和 “右规” 两种。以基数 r = 2 为例:
- 左规:向左规格化。当运算结果尾数的最高数位不是有效位,即出现 0.0…01… 的形式时,需要向左规格化。左规时,尾数左移一位,阶码减 1;
- 右规:向右规格化。当运算结果尾数的小数点左侧出现有效位,即整数部分不为 0 时,需要向右规格化。右规时,尾数右移一位,阶码加 1;需要右规时,只需进行一次。
**当基数不同时,规格化的原则会有相应的改变。**比如,当基数 r = 4 时,阶码每次加/减 1,就相当于多乘/除以 4,也就是左/右移 2 位。所以左规就是尾数左移 2 位,阶码减 1;右规是尾数右移 2 位,阶码加 1。尾数的最高 2 位不全为 0 的数,就是规格化数。
5.浮点数的加/减运算
浮点数运算的特点,是阶码运算和尾数运算分开进行。浮点数加/减运算可以分为 5 步进行:
(1)对阶
对阶的目的是使两个操作数的小数点位置对齐,使两个数的阶码相等。先求阶差,然后以 “小阶向大阶看齐” 的原则,将阶码小的尾数右移一位(基数为2),阶码加1,直到两个数的阶码相等为止。
(2)尾数求和
将对阶后的尾数,按定点数加/减运算规则运算。
(3)规格化
IEEE 754 规格化尾数的形式为 ±1.×…×,所以当计算结果为非规格化数时,需要进行规格化处理。
- 左规:当结果为 ±0.0…01x…x 时,需进行左规。尾数每左移一位,阶码减 1。可能需要左规多次,直到将第一位 1移到小数点左边。
- 右规:当结果为 ±1x.x…x 时,出现了尾数的溢出,需进行右规。尾数右移一位,阶码加 1。当尾数右移时,最高位 1 被移到小数点前一位作为隐藏位;当最后一位移出时,要考虑舍入。
左规一次相当于乘以2,右规一次相当于除以2;需要右规时,只需进行一次。
(4)舍入
在对阶和尾数右规时,尾数右移可能会将低位丢失,影响精度,IEEE 754有以下4种舍入方式:
- 就近舍入:舍入为最近的那个数,类似于 “四舍五入”,一般被叫做 “ 0 舍 1 入” 法;如果被舍入的值恰好是 100…0 形式,选择舍入为最近的偶数;
- 正向舍入:向 +∞ 方向舍入,即取右边那个数,也叫 “向上舍入”;
- 负向舍入:向 -∞ 方向舍入,即取左边那个数,也叫 “向下舍入”;
- 截断:朝 0 方向舍入,即取绝对值较小的那个数。
(5)溢出判断
浮点数的溢出,并不是以尾数溢岀来判断的;尾数溢出可以通过右规操作得到纠正。运算结果是否溢出,主要看结果的指数是否发生了溢出,因此是由阶码来判断的。
- 若一个正阶码超出了最大允许值(127 或 1023),则发生上溢,产生异常;
- 若一个负阶码超出了最小允许值(-149 或 -1074),则发生下溢,通常把结果按机器零处理。
例如,两个数 x = 29/32 × 27,y = 5/8 × 25,用浮点加法计算 x + y。假设浮点数的阶码和尾数均用补码表示,且阶码为 5 位(含 2 位阶符),尾数为 7 位(含 2 位数符)。
首先,将浮点数写成下面的规格化二进制形式:
x = 0.11101 × 2111,y = 0.101 × 2101
具体计算过程如下:
(1)对阶
阶码相减 00, 111 - 00, 101 = 00, 010,说明 x 的阶码比 y 的大 2,需要将 y 的尾数右移两位,阶码加 2:
y = 0.00101 × 2111
(2)尾数求和
尾数相加 00.11101 + 00.00101 = 01.00010
(3)规格化
运算结果的尾数出现溢出,需要进行右规:尾数右移一位,阶码加 1:
1.00010 × 2111 = 0.100010 × 21000,即计算结果为 01, 000; 00, 10001
(4)舍入
结果的尾数用补码表示为:00 10001,不需要舍入。
(5)溢出判断
结果的阶码用补码表示为:01 000,由于阶符为 01,说明结果溢出。
5.校验码
校验码是在二进制信息存储或传输过程中,在要存储或传输的数据信息中额外地添加一些的所谓“冗余”信息(也是二进制形式),以达到能发现(甚至能自动纠正)存储或传输过程中可能发生的错误
检验码:
是由传输的数据信息与额外添加“冗余”信息共同组成的,我们姑且分别
称它们为数据位和校验位。
注意:检验码 = 数据位+校验位。
检验码不等于校验码
5.1奇偶校验码
**奇偶校验码:**就是通过添加校验位保证所传输的校验码(含数据位和校验位)中‘1’的个数为奇数或偶数。
奇校验码:传输的校验码中‘1’的个数为奇数。
偶校验码:传输的校验码中‘1’的个数为偶数。
例如:设采用奇校验码,现在要传输一串数据:01010110,那么就要在数据的最高位或者最低位添加一位校验位,确保将发送的数据中是奇数个‘1’。
接收数据,就可以通过检查‘1’的奇偶性,来判断接收到的数据有无传输错误。如果是奇数则传输无误;如果是偶数则数据传输出现了一位错误。
不过这种方法下,如果同时出现两个或多个错误,使得‘1’的个数恰好符合判断要求,就没法检查出来了。**不过实践统计表明,这种概率极小,即同时出现多个错误的可能性极低。**如此我们提出的方法应该是有效可行的
5.2海明校验码(简称海明码)
奇偶校验码可以判断信息传送是否出错,但是却无法判定出错误位置在何处。
而**海明码:**是通过增加校验位位数的方法,实现不但能检验是否出错,而且能判定具体的出错的位置,这样就能纠错了
海明码的具体做法:
1. 确定校验位的个数
设现有数据位有 k 位待传输,增加 r 位校验位,所以发送的信息一共有 k+r 位校验码。
在传输过程中不仅数据位有可能出错,校验位也可能出错那么传输时可能出错的地方有 k+r 个位置,另外考虑到不出错的也是一种情况,所以传输过程总共有 k+n+1 种状况
假设要发送的数据有 k=6 位,要添加多少个校验位呢?
假设添加 3 个校验位,则现在要发送的是 9 位(6 个数据位,3 个校验位),发生错误的状况将是 9 种,外加不出错状态,共 10 种状况。而 3 位校验位,二进制只能表示 2的3次方 =8 种状态,不能完全表征所有状况,显然不行。
校验位增加到 4 位呢,可以表示 2的4次方 =16 种状况,发送的数据一共 10 位(6 数据,4 校验),再加上 1 种不出错的情况,共 11 种。16>11,所以,校验位 4 位是可行的。
可以得出公式:2 的r次方>=k+r+1
,用它来确定校验位 r 的值
2. 确定校验位的位置
3.确定校验位的值
确定了校验位和数据位的具体位置后,接下来要确定各个校验位的具体值是 0,还是 1。
规则是:校验位的值,要与其相关的位置上的各个数据位形成偶校验
形成偶校验容易理解,就是通过设置 0 或 1,保证 1 的个数是偶数,
那么哪些数据位是与各个校验位相关的呢?
观察一下校验位的位置,只能是 1、2、4、8…,从二进制角度看,分别为:0001、0010、 0100、01000,
可以看出每位校验位对应一位二进制
例如p1的位置是0001 那么只要第一位有1的都与之相关
p2的位置是0010 那么只要第二位有1的都与之相关
所以 P1=0。同理确定其他的校验位 P2和 P3。
4.纠错(译码)
以上 1、2、3 亦统称校验码的**编码。**至此,海明码已经确定了,即要发送的东西已经求出来了。纠错是在接收端进行的处理,即接到之后检查一下有没有出错。
将各校验位按由大到小的顺序与它相关的数据进行异或运算,得到一个二进制序列(称为指误字),整体为值“0”零代表无错;不为“0”代表有错,值的就是出错位置。
简单的说,译码所做的事就是:由于发送时每个校验位和其相关的数据位 1 的个数为偶数,接收到时检查一下是否仍为偶数。若都为偶数,则指误字为“0”,若不都全为偶数,则指误字一定不为“0”,而且其值就是出错位置。
6.存储器
6.1存储器的分类
存储器是计算机系统中的记忆设备,用来存放程序和数据。存储器的种类繁多,从不同的角度对存储器可作不同的分类。
按在计算机中的作用分类
-
主存储器(简称主存):用来存放程序和数据,可以和CPU直接交换信息。
-
辅助存储器(简称辅存):主存储器的后援存储器, 用来存放当前暂时不用的程序和数据, 它不能与CPU直接交换信息。两者相比,主存速度快、容量小、每位价格高;辅存速度慢、容量大、每位价格低。
-
缓冲存储器(简称缓存,Cache) 用在两个速度不同的部件之中。
6.2存储器的性能指标
存储器有 3 个主要性能指标:速度、容量和每位价格(简称位价)。
1.存储速度
- **存取时间:**是完成一次存储器读/写操作所需要的时间,又称为 访问时间
存取时间又分为读出时间和写入时间。读出时间是从存储器接受到有效地址开始,到产生有效输出所需的全部时间;写入时间是从存储器接受到有效地址开始,到数据写入被选中存储单元为止的全部时间。
- 存储器周期: 指连续进行两次独立的存储器操作(读或者写)需要的最小时间间隔,也叫 存取周期
存储器经过一次读写操作后,并不能立即进行下一次读写,中间还需要一段时间来恢复内部状态。所以,
存储器周期 = 存取时间 + 恢复时间
- **存储器带宽:**指单位时间内存储器存取的数据量
单位为位/秒(b/s),或者字节/秒(B/s)、字/秒。
存储器带宽 = 数据宽度 / 存储周期
类似:速度 = 路程 / 时间
例如,存储器周期为 500 ns,每个存取周期可以访问 16 位,那么带宽就是:
16 bit ÷ 500 ns = 32 Mb/s
2. 存储容量
存储容量指存储器能存放的数据总量,一般用二进制代码的总位数(bit)来表示。
存储容量 = 存储字数 × 存储字长
存储字数代表了存储器地址空间的大小,由地址线的位数决定。容量一般也可以用字节总数(Byte)来表示,也就是:
存储容量(字节数) = 存储字数 × 存储字长 / 8
例如,某机器存储字长为 8 位,地址线有 28 位,那么它的主存最大存储容量为:
228 × 8 / 8 = 228 B = 256 MB
3. 位价
每位价格也就是存储器的单位成本。
位价 = 总成本 / 总容量
一般来说,速度越高,位价就越高;容量越大,位价就越低;而且容量越大,速度也会越低。
6.3层次化存储器的基本结构
- **寄存器:**通常都制作在 CPU 芯片内。寄存器中的数直接在 CPU 内部参与运算, CPU 内可以有十几个、几十个寄存器,它们的速度最快,位价最高,容量最小。
- **主存:**用来存放将要参与运行的程序和数据,它与 CPU 速度差距较大。
- **Cache:**为了使主存和 CPU 之间速度更好地匹配, 需要在主存与 CPU 之间插入一种比主存速度更快、容量更小的高速缓冲存储器 Cache,其位价要高于主存。
磁盘、磁带属于辅存,其容量比主存大得多,大都用来存放暂时未用到的程序和数据文件。CPU不能直接访问辅存, 辅存只能与主存交换信息, 因此辅存的速度可以比主存慢得多。
CPU 和缓存、主存都能直接交换信息; 缓存能直接和 CPU、主存交换信息; 而主存可以和 CPU、缓存、辅存交换信息。
- 缓存-主存层次
这一层次主要解决 CPU 和主存速度不匹配的问题。由于缓存的速度比主存的速度高, 只要将CPU近期要用的信息调人缓存, CPU 便可以直接从缓存中获取信息, 从而提高访存速度。但由于缓存的容量小,因此需不断地将主存的内容调入缓存,使缓存中原来的信息被替换掉。主存和缓存之间的数据调动是由硬件自动完成的,对程序员是透明的。
- 主存-辅存层次
这一层次主要解决存储系统的容量问题。辅存的速度比主存的速度低,而且不能和 CPU 直接交换信息, 但它的容量比主存大得多, 可以存放大量暂时未用到的信息。当CPU需要用到这些信息时, 再将辅存的内容调人主存, 供CPU直接访问。主存和辅存之间的数据调动是由硬件和操作系统共同完成的。
从CPU角度来看, 缓存-主存这一层次的速度接近于缓存, 高于主存; 其容量和位价却接近于主存。主存-辅存这一层次,从整体分析,其速度接近于主存,容量接近于辅存,平均位价也接近于低速、廉价的辅存位价。这就解决了速度、容量、成本这三者的矛盾。
6.4 半导体存储器
半导体存储器分为 **随机存取存储器(RAM)**和 只读存储器(ROM)。
RAM 按照存储信息的原理不同,又可以分为静态随机存取存储器**(SRAM)和动态随机存取存储器(DRAM)**,主存储器主要由 DRAM 实现,靠近处理器的那一层缓存 **(Cache)**则由 SRAM 实现,它们都是易失性存储器。ROM 是非易失性存储器。
主存中各个存储单元的空间位置,是由一个地址号来表示的;通过地址总线可以给定一个存储单元的地址号,从而根据地址读出或者写入一个存储字。
地址线和数据共同反映了芯片的存储容量。比如,10 根地址线,4 根数据线,表示芯片的存储容量为:210 × 4 = 4 Kb。
- 地址线是单向输入的,其位数与芯片存储容量有关。
- 数据线是双向输入的,其位数与芯片每次可读出或写入的数据位数有关,从而也影响到存储容量
半导体存储芯片的译码驱动,主要有两种方式:线选法 和 重合法。
- 线选法:是用一根字选择线(字线),直接选中一个存储单元的各位。这种方式结构比较简单,不过只适合用于容量不大的存储芯片。
- 重合法:用两个方向的地址,共同决定选中存储矩阵中的一个存储单元。相比 “一维” 的线选法,重合法就升级到了 “二维”,可以用更少的选择线实现对所有存储单元的选择。
上面是一个采用线选法译码驱动的存储芯片结构示意图。这个芯片有 8 位地址线和 8 位数据线,所以有 28 = 256 个存储字,需要 256 根字线来实现选中每个存储字。
如果采用重合法,则可以使用 X、Y 两个方向的地址译码器分别对 4 位地址进行译码,只需要两个方向各 16 根选择线,就可以直接选中 16 × 16 存储矩阵中的每一位。
当然,在这个示例中,如果用重合法实现 256 个字节(256 × 8)的存储器,需要使用 8 片上面结构的芯片,这样一来总的选择线并没有更少。不过如果考虑更大容量的存储器,比如地址线有 32 位、数据线仍为 8 位时,则线选法需要 232 根字线;而重合法同样是需要 8 片芯片,每片芯片只需 216 × 2 = 217 根选择线就可以实现。
6.4.1SRAM
通常把存放一个二进制位的物理器件称为存储元,它是存储器最基本的构件。地址码相同的多个存储元构成一个存储单元。存储单元的集合构成存储体。
静态 RAM(Static RAM,SRAM)的存储元是用双稳态触发器(六晶体管MOS)来记忆信息的,因此信息被读出后,它仍保持其原状态而不需要刷新;这种读特性被称为“非破坏性读出”。
下面是 Intel 2114 RAM 芯片的存储矩阵结构示意图。2114 芯片有 10 根地址线,其中 6 根行地址线、4 根列地址线,存储矩阵由 64 × 64 个基本单元电路组成,总容量为 1K × 4 位。
SRAM 使用触发器工作原理存储信息,因此在读出信息后,它仍会保持原来的状态,不需要刷新。不过如果电源掉电,存储的信息就会丢失,所以它属于易失性半导体存储器。
SRAM 的存取速度快,但集成度低,功耗较大,价格昂贵,一般用于 Cache。
6.4.2DRAM
动态 RAM(Dynamic RAM,DRAM)是利用存储元电路中栅极电容上的电荷来存储信息的。若电容上存有足够多的电荷表示存 “1”,电容上无电荷则表示存 “0”。
常见的动态 RAM 基本单元电路有三管式和单管式两种。单管式只需要一个 MOS 管和一个电容,因此可以极大地提高集成度。
- 进行读操作之后,电容上的电荷就释放掉了,所以必须进行 “再生” 处理;这种读取方式为 破坏性读出。
- 对于写入操作,同样是字线高电平令 T 导通,如果数据线上为高电平则对电容充电,存入 “1”;如果为低电平则电容放电,存 “0”。
可以看到,DRAM 的基本存储元可以只使用一个晶体管, 所以它比 SRAM 的密度要高很多。为了进一步提高集成度,DRAM 采用 地址复用技术,地址信号分行、列两次传送,这样地址线是原来的一半,地址引脚数也可以减少一半,就能够进一步减小芯片的体积。
下面是 Intel 4116 RAM 芯片的整体结构和存储矩阵示意图。4116 芯片的存储矩阵为 128 × 128,共有 16 K 个单管 MOS 基本单元电路,容量为 16K × 1 位。本来芯片应该有 14 根地址线,不过为了减少芯片封装的引脚数,地址线只有 7 根。这就需要将完整的地址信息分成行地址、列地址两部分(各自 7 位),分两次传送。
相对 SRAM 来说,DRAM 具有容易集成、价位低、容量大和功耗低等优点,但 DRAM 的存取速度比 SRAM慢,一般用于大容量的主存系统。
6.4.3DRAM 的刷新
由于电容上的电荷一般只能维持1 ~2ms
,因此即使电源不掉电,信息也会自动消失。为此,必须在 2ms
内对所有存储单元恢复一次原状态,这个过程称为 再生 或者 刷新。
刷新的过程,实质上是先将原存信息读出,再由刷新放大器形成原信息并重新写入的再生过程。由于存储单元是被随机访问的,有些存储单元可能一直不会被访问,因此其存储的原信息将会慢慢消失。因此,必须进行定时刷新。一般要求在一定的时间内,对动态 RAM 的全部基本单元必须作一次刷新,这个时间称为 刷新周期,也叫 再生周期,一般取 2ms。
(1)集中刷新
在规定的一个刷新周期内,对全部存储单元集中一段时间进行逐行刷新;刷新时必须停止读/写操作。
例如,我们有一个芯片的存储矩阵为 128 × 128,它的存取周期为 0.5 μs,刷新周期为 2 ms(4000 个存取周期),那么对它的 128 行存储单元进行集中刷新需要:
0.5 μs × 128 = 64 μs
那剩余的 1936 μs(3872个存取周期)就可以用来读/写或者维持信息。由于在这 64 μs 内无法进行读/写操作,所以这段刷新时间被称为 “死时间”,也叫访存 “死区”。死时间占据存取周期的比例 64 μs / 2 ms × 100% = 3.2%,称为死时间率。
(2)分散刷新
对每行存储单元的刷新,分散到每个存取周期内完成。这样,每个存储周期 tC 就分成了两段:前半段 tM 用来读/写或者维持信息,后半段 tR 用来刷新。所以:
tC = tM + tR
同样以 128 × 128 存储矩阵的芯片为例,读/写周期 tM = tR = 0.5 μs,那么存取周期 tC = 1 μs。逐行进行刷新,每隔 128 μs 就可以将存储芯片全部刷新一遍。
这样的好处是不存在停止读/写操作的死时间,而且刷新间隔比要求的刷新周期 2ms 短得多;缺点在于存取周期 tC 变长了,使得整个系统速度变慢。
(3)异步刷新
异步刷新是前两种方式的结合,它既可以缩短 “死时间”,又能充分利用最大的刷新间隔 2ms。
还是之前的例子,对于 128 × 128 存储矩阵的芯片,存取周期 tC = 0.5 μs,可以让它把对 128 行的刷新平均分配到 2ms 的刷新周期内。也就是说,每隔 2ms ÷ 128 ≈ 15.6 μs 刷新一行,每次刷新的时间还是一个存取周期 tR = 0.5 μs。
这样一来,2ms 内用于刷新的时间仍然是 128 tR = 64 μs,而由于分散到了整个刷新周期内,每次刷新一行只停了一个存取周期;所以对于每行来说,刷新的间隔还是 2ms,而 “死时间” 缩短为 0.5 μs。
如果将 DRAM 的刷新安排在 CPU 对指令的译码阶段,由于这个阶段 CPU 不会访问存储器,所以这样就完全避免了 “死时间” 的问题,从根本上提高了机器效率。
6.4.4DRAM 和 SRAM 的比较
目前,随着 DRAM 的容量不断扩大,速度不断提高,它的应用要比 SRAM 更加广泛。DRAM 主要用在计算机的主存中,而 SRAM 通常用于容量不大的高速缓存(Cache)中。
两者的特点可以比较如下:
6.4.5 ROM
ROM (Read Only Memory)最原始的定义是 “只读存储器”,一旦写入原始信息后就不能更改。所以ROM 通常用来存放固定不变的程序、常数和汉字字库,甚至用于操作系统的固化。它与随机存储器可共同作为主存的一部分,统一构成主存的地址域。
不过随着用户的需要和技术的发展,又出现了更多类型的 ROM,让用户拥有了修改数据的能力。
根据制造工艺不同,ROM 可分为固定掩模型 ROM(MROM)、一次可改写 ROM (PROM)、紫外线擦除电可编程 ROM(EPROM)、电擦除电可编程 ROM (EEPROM)、快擦写**(Flash)**存储器。
Flash
闪速存储器(闪存,Flash),又称快擦型存储器,是在 EEPROM 的工艺基础上发展而来的,性价比更好、可靠性更高。其主要特点有:
- 价格便宜、集成度高;
- 属非易失性存储器,适合长期保存信息;
- 能快速擦写(电可擦除),写入前必须先擦除,因此写比读要慢。
由于 Flash 的擦除、重写时间已经非常短,比一般的 EEPROM 要快得多,所以 Flash 已经具备了 RAM 的功能,可以与 CPU 直接相连。电脑的 BIOS 程序由于包含了开机后的自检程序和自举装载程序,一般都会固化到主板上的一个 ROM 芯片中;如今的电脑通常就会用 Flash 芯片来存放 BIOS 程序。
Flash 可以至少擦写 10000 次以上,而且是非易失性存储器,所以在需要周期性修改存储信息、并长期保存的场合,它是一个非常理想的存储器;比如工控系统、单片机中作为数据采集和存储器件,用于制作 U 盘和移动硬盘等。
目前随着闪存技术的发展,容量越来越大、价格越来越低,让大容量 Flash 取代磁盘成为了可能。用闪存技术做成 固态硬盘(SSD),可以代替传统的磁盘,速度更快,功耗更低,体积更小。如今很多笔记本电脑中都使用了 SSD,使得计算机平均无故障时间大大延长。
SRAM、DRAM 和 ROM 这 3 种存储器的特点可以总结如下。
6.5主存储器
6.5.1主存储器的基本组成
主存储器简称主存或内存,是计算机中存储程序和数据的重要部件。主存内包含了存储体、各种逻辑部件以及控制电路等
主存是通过按地址访问的方式,对存储体内的存储单元进行读写操作的。因此主存首先需要从 MAR 中获取地址,由译码器进行地址译码、再经过驱动电路,进而通过选择线选中所需访问的单元。读出时,需要经过读出放大器才能将被选中存储单元的内容送到 MDR;写入时,MDR 中的数据也需要经过写入电路才能真正存入被选中的单元。所以主存实际结构的基本组成如下:
译码器、驱动器和读写电路都集成在 DRAM 存储芯片中,而 MAR 和 MDR 则集成在 CPU 芯片内。存储芯片可以通过总线与 CPU 相连。
当要从主存中读某个数据字时,首先由 CPU 将字的地址送到 MAR,通过地址总线送至主存,然后发出读命令;主存的译码器将地址总线送来的地址译码,导通对应存储单元的选择线,收到读信号后,便将该单元的内容送到数据总线上,进而交给 MDR。
如果要向主存写入一个数据字,仍然需要 CPU 先把地址送到 MAR,并把要写的数据送到 MDR,然后发出写命令;主存译码器依然从地址总线读取地址进行译码,接到写命令后,就把数据线上的信息写入对应的存储单元。
译码器(复习)
译码器是一种具有 “翻译” 功能的组合逻辑电路器件,可以将以二进制码表示的输入状态,转换成对应的特定输出信号。“译码” 就是 “编码” 的逆过程。
对于 n 位信号输入,译码器对应有 2n 个输出。译码器可以用逻辑门电路很容易实现。
存储器中的地址译码器,就是以 n 位地址线作为输入,以 2n 根选择线作为输出的译码器。当输入一个地址信号时,地址可以看作一个二进制数,它对应的十进制数就是选择线的序号。
主存中地址的分配
主存中各存储单元的空间位置,都是由存储单元的地址号表示的;地址总线的作用就是给出要访问的存储单元的地址。每次访问存储单元,可以读出或者写入一个存储字。
存储字长必须是字节(8位)的整数倍,不同机器的存储字长不同。计算机一般既可以按字来寻址,也可以按字节寻址。例如,一台机器的存储字长为 32 位,并且可以按字节寻址,那么它的每个存储字都包含了 4 个具有独立地址的字节,地址的分配方式如下:
字地址是用该字高位字节的地址来表示,所以字地址总是 4 的整数倍,即二进制末两位总是 0。这样,对于同一个字内的字节,可以用地址末两位来进行区分,高位则是完全相同的。
如果这台机器的地址线为 24 位,那么按字节寻址的范围是 224 = 16M,按字寻址的范围为 16M / 4 = 4 M。
6.5.2主存和 CPU 之间的连接
早期的内存就只是一块芯片,直接焊接在主板上;这样很难拆卸、更换,无法轻易扩容升级。内存条 的出现使得内存的更换和升级更加方便。内存条的主体是一块印制电路板(PCB),上面一般焊有多个内存芯片。通过印制板边缘的一排金色引脚(“金手指”)可以很容易地插入主板上的内存插槽,与 CPU 进行连接和数据交换。
1. 主存容量扩展
单片存储芯片的容量有限,很难满足我们实际应用的需要,所以主存一般不会直接使用单个芯片实现,而是需要将多个存储芯片连在一起扩展成更大的存储器。这称为 存储容量的扩展,主要的方法有 位扩展 和 字扩展。
(1)位扩展
位扩展是指对字长进行扩展,也就是增加存储字长。这种情况下,系统地址线位数等于芯片地址线位数,而系统数据线位数多于芯片数据线位数。
位扩展的连接方式:各芯片的地址线、片选线和读写控制线与系统总线相应 并联;各芯片的 数据线单独引出,分别连接系统数据线。各芯片同时工作。
以之前介绍过的 SRAM 芯片 2114 为例,它的存储容量为 1K × 4,那么用 2 片 2114 采用位扩展的方式可以组成 1K × 8 的存储器。如下所示:
(2)字扩展
字扩展是指对存储字的数量进行扩展,而存储字的位数满足系统要求。这种情况下,系统数据线位数等于芯片数据线位数,系统地址线位数多于芯片地址线位数。
字扩展的连接方式:各芯片的地址线与系统地址线的 低位对应相连,芯片的数据线和读写控制线与系统总线相应 并联;由系统地址线的 高位译码 得到各芯片的片选信号。各芯片分时工作,同一时间只能有一个芯片被选中。
例如,用 2 片容量为 1K × 4 的 2114 芯片,采用字扩展的方式可以组成 2K × 4 的存储器。如下所示:
扩展之后的地址线为 11 位,共有 211 = 2 K 个地址。其中:
- 第一片 2114 的地址范围为 000 0000 0000 ~ 011 1111 1111;
- 第二片 2114 的地址范围为 100 0000 0000 ~ 111 1111 1111。
(3)字和位同时扩展
字和位同时扩展是前两种扩展的组合,这种方式既增加存储字的数量,又增加存储字长。
字和位同时扩展的连接方式:将进行位扩展的芯片作为一组,各组的连接方式与位扩展相同;由系统地址线高位译码产生若干个片选信号,分别接到各组芯片的片选信号。
例如,用 8 片容量为 1K × 4 的 2114 芯片,字和位同时扩展之后可以组成 4K × 8 的存储器。如下所示:
扩展之后的地址线为 12 位,共有 212 = 4 K 个地址。其中:
- 第一、二片 2114 通过位扩展构成第一组,地址范围为 0000 0000 0000 ~ 0011 1111 1111;
- 第三、四片 2114 通过位扩展构成第二组,地址范围为 0100 0000 0000 ~ 0111 1111 1111;
- 第五、六片 2114 通过位扩展构成第三组,地址范围为 1000 0000 0000 ~ 1011 1111 1111;
- 第七、八片 2114 通过位扩展构成第四组,地址范围为 1100 0000 0000 ~ 1111 1111 1111。
2. 主存与CPU的连接
(1)合理选择存储芯片。通常选用 ROM 存放系统程序,选用 RAM 组成用户区。
(2)地址线的连接。CPU 地址线的低位与存储芯片的地址线相连,以选择芯片中的某一单元(字选);CPU 地址线的高位在扩充存储芯片时用,以选择存储芯片(片选)。
(3)数据线的连接。比较CPU的数据线数与存储芯片的数据位数。如果相等可以直接相连;如果不等,必须对存储芯片进行扩位,使其数据位数与 CPU 的数据线数量相等。
(4)读/写命令线的连接。CPU 的读/写命令线一般可以直接与存储芯片的读/写控制端相连。
(5)片选线的连接。片选信号一般由系统地址线高位译码,它是主存与 CPU 连接的关键。
6.5.3多模块存储器
6.5.4外部存储器
6.6高速缓冲存储器(Cache)
为了解决 CPU 和主存之间速度不匹配的问题,计算机系统中引入了高速缓存(Cache)的概念。基本想法就是使用速度更快但容量更小、价格更高的 SRAM 制作一个缓冲存储器,用来存放经常用到的信息;这样一来,CPU 就可以直接与 Cache 交换数据,而不用访问主存了。
- 时间局部性:如果一个数据现在被访问了,那么以后很有可能也会被访问
- 空间局部性:如果一个数据现在被访问了,那么它周围的数据在以后可能也会被访问
局部性原理是 Cache 高效工作的理论基础。
6.6.1Cache 的基本工作原理
为了便于 Cache 与主存交换信息,Cache 和主存都被划分为相等的块,
由于 Cache 的容量远小于主存的容量,所以 Cache 中的块数要远少于主存中的块数,Cache 中仅保存主存中最活跃的若干块的副本
Cache 块又称 Cache 行,每块由若干字节组成,块的长度称为块长
1. Cache 工作原理
假设主存按字节编址,地址用 n 位二进制码表示,那么主存容量为 2n B;块的大小为 16 个字节,那么主存中块的个数为:2n / 16 = 2n-4。那么如果对每个块也做一个编号,其实就对应着地址中的前 n - 4 位。
主存地址就分成了两部分:高 n - 4 位表示主存中的 “块地址”,低 4 位表示 “块内地址”,块内地址其实就是具体存储字在块内的 “偏移量”
Cache 中地址也可以分成这样的两部分,由于 Cache 中块长与主存一致,所以低 4 位同样是块内地址;剩余的高位则为 Cache 的块号。Cache 的块号位数小于 n - 4
所以,可按照某种策略预测 CPU 在 未来一段时间内要访存的数据,将其装入 Cache。当 CPU 要读取主存中的某个字时,分为两种情况:
- Cache 命中:需要的字已经在缓存中,就将其地址转换为缓存地址,直接访问 Cache,与主存无关;
- Cache 未命中:需要的字不在缓存中,仍需访问主存,并将该字所在的块一次性地从主存调入 Cache。
由于 Cache 容量有限,当 Cache 已满时,就需要根据某种替换算法,让需要调入 Cache 的块替换之前某个缓存块的内容
所以,一个缓存块不可能永远只对应一个主存块;需要给每个缓存块设置一个标记,写入当前对应的主存块号,表示它当前存放了哪个主存块。
2. 命中率
Cache 的效率,通常用 命中率 来衡量。命中率是指 CPU 要访问的信息已经在 Cache 中的比率。Cache 的容量和块长都是影响命中率的重要因素。
假设一个程序执行期间,访问 Cache 的总命中次数为 Nc,访问主存的总次数为 Nm,那么命中率为:
h
=
N
c
N
c
+
N
m
h = \frac{N_c}{N_c + N_m}
h=Nc+NmNc
设 tc 为命中时的 Cache 访问时间,tm 为未命中时的主存访问时间,那么 Cache - 主存系统的平均访问时间 ta 为:
t
a
=
h
t
c
+
(
1
−
h
)
t
m
t_a = ht_c + (1-h)t_m
ta=htc+(1−h)tm
由于 tc 远小于 tm,因此平均访问时间 ta 越接近 tc 就说明 Cache 效率越高。用 e 表示访问效率,则有:
e
=
t
c
t
a
×
100
%
=
t
c
h
t
c
+
(
1
−
h
)
t
m
×
100
%
e = \frac {t_c}{t_a} \times 100\% = \frac{t_c}{ht_c + (1-h)t_m} \times 100\%
e=tatc×100%=htc+(1−h)tmtc×100%
命中率 h 越接近 1,访问效率就高。一般来说,Cache 容量越大,命中率就越高;而块长与命中率的关系较为复杂,它取决于程序的局部特性,一般取每块 4 ~ 8 个可编址单位(字或字节)效果较好。
3. Cache 的基本结构
Cache 主要由 Cache 存储体、主存 - Cache 地址映射变换机构、Cache 替换机构几大模块组成。
(1)Cache 存储体
Cache 存储体以块为单位与主存交换信息,Cache 访存的优先级最高。
(2)主存 - Cache 地址映射变换机构
地址映射变换机构会将 CPU 送来的主存地址转换为 Cache 地址。由于主存和 Cache 块长相同,所以块内地址是不变的,地址变换主要就是主存的块号(高位地址)到 Cache 块号之间的转换。这涉及到一个函数的映射关系,被称为 地址映射。
(3)Cache 替换机构
地址转化之后,如果 Cache 命中,CPU 就直接访问 Cache 存储体;如果不命中,CPU 需要访问主存将需要的字取出,并把它所在的主存块调入 Cache。如果 Cache 已满,无法将主存块直接调入 Cache,就需要 Cache 内的替换机构执行替换策略。
所谓替换策略,就是按一定的替换算法,确定从 Cache 中移出哪个块返回主存,并把新的主存块调入 Cache 进行替换。
在执行写操作时,还需要考虑如何使 Cache 如何与主存的内容保持一致。这就需要用某种 Cache 写策略。
4. Cache 的改进
Cache 的改进,主要就是由一个缓存改为使用多个缓存。主要有两个方向:增加 Cache 级数;将统一的 Cache 变为分立的 Cache。
(1)两级缓存
最初在 CPU 和主存之间只设一个缓存,称为 单一缓存。随着集成电路密度的提高,这个缓存就直接与 CPU 集成在了一个芯片中,所以又称为 片内缓存(片载缓存)。
由于片内缓存容量无法做到很大,所以可以考虑在片内缓存和主存之间再加一级缓存,称为 片外缓存,也由 SRAM 组成。这种由片外缓存和片内缓存构成的 Cache 系统被称为 “两级缓存”,片内缓存作为第一级(L1 Cache),片外缓存作为第二级(L2 Cache)。
(2)分立缓存
指令和数据都存放在同一缓存内的 Cache,称为 统一缓存;而 分立缓存 则将指令和数据分别存放在两个缓存中,一个叫指令 Cache,另一个叫数据 Cache。这两种缓存的选择主要考虑两个因素:
- 主存结构。如果计算机主存中指令、数据是统一存储的,则相应的 Cache 采用统一缓存;如果主存指令、数据分开存储,则相应的 Cache 采用分立缓存。
- 机器对指令执行的控制方式。如果采用了超前控制或者流水线控制方式,一般都采用分立缓存。所谓超前控制,是指在当前指令执行尚未结束时就提前把下一条准备执行的指令取出;而所谓流水线控制,就是多条指令同时分阶段执行。
6.6.2Cache 和主存之间的映射方式
Cache 块中的信息是主存中某个块的副本,地址映射是指把主存地址空间映射到 Cache 地址空间,这相当于定义了一个函数:
Cache 地址 = f ( 主存地址 )
当然,由于 Cache 和主存块长一样,而块内地址只是字在当前块内的 “偏移量”,所以映射转换之后块内地址是不变的。我们需要的其实只是 Cache 块号和主存块号之间的函数关系:
Cache 块号 = f ( 主存块号 )
Cache 块远少于主存块,所以 Cache 块不可能永远对应唯一的主存块,需要在 Cache 中为每一个块加一个 标记,指明它是主存中哪一块的副本。这个标记的内容,应该能够唯一确定对应主存块的编号。另外,为了说明 Cache 行中的信息是否有效,每个 Cache 行还需要有一个 有效位,该位为 1 时,表示 Cache 中该映射的主存块数据有效;为 0 则无效。
地址映射的方法有以下 3 种。
1. 直接映射
**直接映射 **的思路非常简单,就是 “挨个对应”,主存中的每一块只能装入 Cache 中的唯一位置。
由于 Cache 容量很小,当主存中的块已经 “遍历” 完所有 Cache 地址后,下一个主存块的对应位置就又成了 Cache 中的第一行(第一个块)。
很明显,这跟 “顺序存储” 的思路是一样的,用主存块号对 Cache 的总行数取模,就可以得到对应 Cache 的行号了:
Cache行号 = 主存块号 mod Cache总行数
例如,假设主存地址为 32 位,按字节编址,主存块大小为 64 B,所以主存块共有 232 / 64 = 226 个;如果 Cache 只有 4 行(4 个块),那么采用直接映射方式的对应关系如下:
更加一般化,假设 Cache 共有 2c 行,主存有 2m 个块,那么 Cache 行号有 c 位,主存块号有 m 位。在直接映射方式中,主存块号为 0、2c、2c+1… 的块,都映射到 Cache 的第 0 行;而主存中块号为 1、2c + 1、2c+1 + 1… 的块,映射到 Cache 的第 1 行;以此类推。
这样一来,主存块号的低 c 位就对应了 Cache 中的行号;当一个块存放在 Cache 中,只需要高 m - c 位就可以指明它对应的主存中的块号。给每个 Cache 行设置一个 t = m - c 位的标记,那么当主存某块调入 Cache 后,就将其块号的高 t 位设置在对应 Cache 行的标记中。
所以直接映射方式下,主存地址结构为:
访存过程:
① 根据访存地址中间的 c 位,找到对应的 Cache 行。
② 将该 Cache 行中的标记和主存地址的高 t 位标记进行比较。
③ 若相等且有效位为1,则 Cache 命中,此时根据主存地址中低位的块内地址,在对应的 Cache 行中存取信息;若不相等或有效位为 0,则 Cache 未命中,此时 CPU 从主存中读出该地址所在的一块信息,并送至对应的 Cache 行中,将有效位置 1,并置标记为地址中的高 t 位。
直接映射实现简单,但不够灵活,即使 Cache 的其他许多地址空着也不能占用,这使得直接映射的块冲突概率高,空间利用率低。
2. 全相联映射
直接映射的问题在于,我们找到的是从主存块到缓存行的一种 “多对一” 的关系,每一个主存块只能对应唯一的缓存行,从而导致冲突概率高。如果让一个主存块,可以映射到多个缓存块上,变成 “多对多” 的关系,明显就可以减少冲突了。
最简单的情况,就是不加任何条件限制,让主存的每一个块都可以映射到 Cache 的任意位置;简单来说就是 “有空就填”,放在哪里都可以。这就是 全相联映射 方式。
由于没有任何规律,所以当一个块存放在 Cache 中,无法根据 Cache 行号推出它对应主存块的任何信息;因此必须在每行的标记中明确指出该行取自主存的哪一块,这样标记就需要完整的 m 位主存块号。CPU 访存时,需要与所有 Cache 行的标记进行比较。
全相联映射方式下,主存的地址结构为:
全相联映射方式的优点是灵活,Cache块的冲突概率低,空间利用率高,命中率也高;缺点是标记的速度较慢,实现成本较高,通常需采用昂贵的按内容寻址的相联存储器进行地址映射。
3. 组相联映射
把直接映射和全相联映射两种方式结合起来,就是 组相联映射 方式。
组相联的思路是将 Cache 分成 Q 个大小相等的组,每个主存块可装入对应组的任意一行;它所在的组则按顺序依次排列得到。也就是 组间采用直接映射、而 组内采用全相联映射 的方式。当 Q=1 时,变为全相联映射;当 Q = Cache 行数时变为直接映射。
假设每组有 R 个 Cache 行,则称之为 R 路组相联;例如每组有 2 个 Cache 行时称为 2 路组相联。
类似的例子,假设主存地址为 32 位,按字节编址,主存块大小为 64 B,所以主存块共有 232 / 64 = 226 个;如果 Cache 有 8 行(8 个块),采用 2 路组相联映射方式,那么共有 Q = 8 / 2 = 4 组。对应关系如下:
可以看出,现在的 “组号” 就相当于直接映射方式下的行号,可以由主存块号对组数 Q 取模得到:
Cache组号 = 主存块号 mod Cache组数
更加一般化,假设 Cache 共有 2c 行,分为 Q = 2q 组,主存有 2m 个块;那么 Cache 行号有 c 位,其中高 q 位是组号,主存块号有 m 位。这时每组中的 Cache 行数为 R = 2c / Q = 2c-q ,行号的低 c - q 位就代表了 Cache 行在组内的序号。
在 R 路组相联映射方式中,主存块号为 0、2q、2q+1… 的块,都映射到 Cache 的第 0 组,可以选择组内 2c-q 行的任一行;而主存中块号为 1、2q + 1、2q+1 + 1… 的块,映射到 Cache 的第 1 组,同样可以任选组内的 Cache 行;以此类推。
这样一来,主存块号的低 q 位就对应了 Cache 中的组号;当一个块存放在 Cache 中,只需要高 m - q 位就可以指明它对应的主存中的块号。给每个 Cache 行设置一个 t = m - q 位的标记,那么当主存某块调入 Cache 后,就将其块号的高 t 位设置在对应 Cache 行的标记中。
所以组相联映射方式下,主存地址结构为:
访存过程:
① 先根据访存地址中间的 Cache 组号,找到对应的 Cache 组。
② 然后将该组中每个 Cache 行的标记与主存地址的高位标记进行比较。
③ 若有一个相等且有效位为1,则 Cache 命中,此时根据主存地址中的块内地址,在对应 Cache 行中存取信息;若都不相等,或虽相等但有效位为 0,则 Cache 未命中,此时 CPU 从主存中读出该地址所在的一块信息,并送至对应 Cache 组的任意一个空闲行,将有效位置 1,并设置标记。
组相联映射方式下,路数 R 越大,即每组 Cache 行的数量越多,发生块冲突的概率越低,但比较电路也越复杂。
可以将以上 3 中映射方式对比如下:
6.7虚拟存储器
习题
1.某机器字长 16 位,采用单字长指令,每个地址码 6 位。试采用操作码扩展技术,设计 14 条二地址指令,80 条一地址指令,60 条零地址指令。请给出指令编码示意图。
指令字长(Instruction Length)
指令字长是指计算机指令的长度,通常以比特(bits)或字节(bytes)为单位。指令字长决定了一条指令在内存中占用的空间和指令的格式。在不同的计算机体系结构中,指令字长可能是固定的,也可能是可变的。
机器字长(Word Length)
机器字长是指计算机中处理器一次可以处理的二进制数据的位数,也是计算机内部数据处理的基本单位。机器字长通常决定了计算机的寄存器大小、数据总线宽度和内存地址的最大范围。常见的机器字长有8位、16位、32位和64位。
关系
机器字长决定了处理器一次可以处理和传输的数据位数。如果指令字长是机器字长的整数倍,那么指令的传输和处理将更加高效。例如,在一个32位处理器上,如果指令字长是32位,那么处理器可以在一个时钟周期内获取和处理一条指令。
5.3 某机字长 16 位,CPU 地址总线 18 位,数据总线 16 位,存储器按字编址,CPU 的控制信号线有:MREQ #(存储器访问请求,低电平有效),R/W #(读写控制,低电平为写信号,高电平为读信号)。
试问:
(1)该机可以配备的最大主存容量为 。
(2)该机主存采用 64K×1bit 的 DRAM 芯片(内部为 4 个 128×128 阵列)构成最大主存空间,则共需 个芯片;若采用异步刷新方式,单元刷新间隔为 2ms,则刷新信号的周期为 。
(3)若为该机配备 2K×16 位的 Cache,每块 8 字节,采用 2 路组相联映象,试写出对主存地址各个字段的划分(标出各个字段的位数);若主存地址为 462EH,则该地址可映象到 Cache 的哪一组?
(4)已知该机已有 8K×16 位的 ROM 存储器,地址处于主存的最高端;现在再用若干个 16K×8 位的SRAM 芯片形成 128K×16 位的 RAM 存储区域,起始地址为 00000H,假设 SRAM 芯片有 CS#(片选,低电平有效)和 WE#(写使能,低电平有效)信号控制端;试写出 RAM、ROM 的地址范围,并画出 SRAM、ROM 与 CPU 的连接图,请标明 SRAM 芯片个数、译码器的输入输出线、地址线、数据线、控制线及其连接。
256kw == 512kb 每个word是16位,等于2字节
256 * 1024 * 2 = 524,288 字节
第三题要解决这个问题,我们需要了解以下几个概念:
- 字(word):在此题中,每个字是16位。
- 主存地址总线:18位。
- Cache大小:2K×16位(2K字,每个字16位)。
- Cache块大小:8字节(每块包含4个字,因为1字=2字节)。
- 组相联映像:2路组相联。
确定cache参数
Cache 总容量:2K字 = 2的11次方。
块大小:8字节 = 4字。
块数:2的11次方除以4 = 2的9次方。
组数:2的9次方除以2 = 2的8次方。
主存块号:
- 块数 = 2的18次方 除以 4 = 2的16次方 m = 16
块内地址:
- b = n - m = 2
组号:
- q = 8位
标记(Tag):。
- 标记位数 = m - q = 16 - 8 = 8位。
标记的作用:Cache 中为每一个块加一个 标记,指明它是主存中哪一块的副本。这个标记的内容,应该能够唯一确定对应主存块的编号
Cache组号的作用:组的多少
块内地址的作用:只是字在当前块内的 “偏移量”,所以映射转换之后块内地址是不变的
若主存地址为 462EH,则该地址可映象到 Cache 的哪一组?
462EH 转换为二进制: 462EH=00 0100 0110 0010 1110
cache组号为 10 0010 11
第4题
单位换算
基本单位
- 比特(bit, b):计算机存储的最小单位,0或1。
- 字节(byte, B):8个比特。
常用单位换算
-
千字节(Kilobyte, KB)
- 1 KB = 1024 B
-
兆字节(Megabyte, MB)
- 1 MB = 1024 KB = 1024 × 1024 B = 1,048,576 B
-
吉字节(Gigabyte, GB)
- 1 GB = 1024 MB = 1024 × 1024 KB = 1024 × 1024 × 1024 B = 1,073,741,824 B
-
太字节(Terabyte, TB)
- 1 TB = 1024 GB = 1024 × 1024 MB = 1024 × 1024 × 1024 KB = 1024 × 1024 × 1024 × 1024 B = 1,099,511,627,776 B
其他常用单位
- 千比特(Kilobit, Kb)
- 1 Kb = 1024 b
- 兆比特(Megabit, Mb)
- 1 Mb = 1024 Kb
- 吉比特(Gigabit, Gb)
- 1 Gb = 1024 Mb
注意事项
- 在某些情况下,尤其是在网络带宽和存储容量等领域,有时使用十进制系统,即 1 KB = 1000 B。这种情况下的换算单位有时被称为 KB (千字节), MB (兆字节), GB (吉字节) 等。十进制和二进制换算单位在实际使用时要注意区分。
在计算机体系结构中,一个“字”(word)的大小可以有所不同,取决于计算机系统的设计。一般来说,一个字的大小是根据系统的 CPU 设计来定的。在一些系统中,一个字是16位(2字节),在其他系统中,一个字可能是32位(4字节)或64位(8字节)。下面是一些解释:
字的大小定义
-
字(word)
:是计算机处理数据的基本单位。一个字的大小通常由处理器架构决定。
- 16位系统:在16位系统中,一个字通常是16位(2字节)。
- 32位系统:在32位系统中,一个字通常是32位(4字节)。
- 64位系统:在64位系统中,一个字通常是64位(8字节)。