基于里昂学长的计算机组成原理课程。
笔记目录
第一章-计算机系统概述
第二章-数据的表示和运算
第三章-存储系统
第四章-指令系统
第五章-中央处理器
第六章-总线
第七章-输入输出系统
第三章 存储系统
3.1 存储器概述
3.1.1 存储器的分类
计算机采用的是“存储程序”的工作方式,存储器相当于计算器的“仓库”。
按存储器在计算机系统中的作用分类
- 主存:用来存放计算机运行期间需要的程序和数据,CPU可直接随机地进行读写访问,存取速度快。由于CPU需要频繁地访问主存,主存的性能很大程度上影响了整个计算机系统的性能。
外存:又称为辅助存储器或后援存储器,用来存放当前暂不参与运行的程序和数据以及一些需要永久性保存的信息(非易失性)。辅存设在主机外部,容量极大且成本很低,但是存取速度低,CPU不能直接访问它。信息必须调入主存后,CPU才能使用。
Cache:由于CPU速度太快了,还需要在CPU和主存之间增加高速缓冲存储器(Cache)。Cache存放正在执行的程序段和数据,存取的速度可以和CPU相匹配,但是存储容量较小,价格较高,通常将它们或它们的一部分制作在CPU芯片中。
按存取方式分类
按存取方式不同可以分为随机存储器(RAM),只读存储器(ROM),顺序存取存储器,直接存取存储器和相连存储器。
- 随机存储器(RAM,Random Access Memory)
优点:随机存取指的是CPU对RAM任一单元的读写时间相同,读写时间与物理地址无关。
缺点:一旦断电就失去信息(易失性)。
分类:还可以进一步分为静态RAM(SRAM)和动态RAM(DRAM)。SRAM多用于制造高速缓冲存储器(Cache)和快表(TLB),DRAM多用于制造主存。
- 只读存储器(ROM,Read-Only Memory)
优点:断电以后不会丢失存储信息(非易失性),适合存储固定程序和数据,多用于系统BIOS和微程序控制器中的控制存储器。
缺点:ROM存储器中的信息一旦写入,之后只能读取,不能再次写入,里面的内容固定不变。
RAM和ROM的存取方式均为随机存取,都是对CPU传入的地址信号进行译码。如今广义上的只读存储器(ROM)已经可以通过电擦除等方式进行写入,比如闪存,固态硬盘,但是仍然保留了断电内容保留、随机读取特性,但是与RAM不同的是他们的写入速度比读取速度慢得多。
- 顺序存取存储器(SAM,Sequential Access Memory)
最常见的顺序存取存储器是磁带。
特点:内容只能按某种顺序存取,必须顺着存储单元的物理地址顺序顺序进行访问(串行访问),存取时间与存取的物理地址相关。
- 直接存取存储器(DAM,Direct Access Memory)
最常见的直接存取存储器是磁盘、光盘。
特点:访问DAM时,先通过随机访问确定一个较小的存储区域(比如磁盘的磁道),再在这个小区域内进行顺序查找,存取时间同样与存取的物理地址有关。
- 相联存储器
相联存储器也称为按内容访问存储器,按照内容寻址,也支持按地址寻址。效率更高,但造价也更贵,例如Cache,TLB。
按信息的可保存性分类
断电后存储信息消失的存储器为易失性存储器,例如RAM。
断电后存储信息仍旧保存的存储器为非易失性存储器,例如ROM、磁盘、磁带、光盘。
按存储器的读出方式分类
- 破坏性读出:所读信息在读出后若不加恢复,则存储器存储的信息会丢失,需要读出后恢复存储信息(再生),例如磁性存储器和DRAM的读出属于破坏性读出。
- 非破坏性读出:读出存储器的内容时不会丢失信息,不需要恢复数据,例如SRAM、ROM、磁盘、磁带、光盘。
按存储介质分类
按存储介质,存储器可以分为磁表面存储器(磁盘、磁带)、磁芯存储器、半导体存储器(MOS型存储器、双极型存储器)和光存储器(光盘)。
- 磁存储器
磁存储器以磁性材料作为存储介质,包括磁芯、磁盘、磁带存储器等,体积大、存取速度慢,但是单位容量成本最低。
- 光存储器
光存储器利用介质的光学特性读出数据,例如CD-ROM、DVD-ROM。光盘存储器便于携带,成本低廉,适用于电子出版物的发行。
- 半导体存储器
用半导体器件组成的存储器成为半导体存储器。主存就是用半导体存储器构造的。
半导体存储器体积小、存储速度快,但单位容量成本相对较高。目前有两大类:双极型存储器,金属氧化物半导体存储器(简称MOS存储器)。MOS存储器又分为静态MOS存储器(SRAM)和动态MOS存储器(DRAM)。
3.1.2 存储器的主要性能指标
存储器的主要性能指标有三个,即存储容量
、单位成本
和存储速度
。
- 存储字
一个二进制数作为一个整体存入或取出时,这个数称为存储字
(存储字长看MDR)。
- 存储单元
存放存储字或存储字接的主存空间称为存储单元或主存单元,大量存储单元的集合构成一个存储体。一个存储单元可能存放一个字,也可能存放一个字节。
- 编址与寻址
存储单元的编号称为地址。编址是给每个单元编号,寻址是找到存储单元编号的过程。
对于字节编址的计算机,最小寻址单位是一个字节,可以按字节、半字、字寻址。
对于字编址的计算机,最小寻址单位是一个字,仅支持按字寻址。
- 主存的读写操作
存储容量
对于字节编址的计算机,以字节数来表示存储容量;对于字编址的计算机,以字数与字长的乘积表示存储容量。
$存储容量=存储字数字长$。例如(1M8位)。存储字数表示存储器的地址空间大小,字长表示一次存取操作的数据量。
如果某计算机的主存容量为64K*16 ,表示它有64K个存储单元,每个存储单元的字长为16位。
单位成本
每位价格=总成本/总容量。
存储速度
存储器速度可用访问时间
、存储周期
或带宽
来表示。
$数据传输速率=数据的宽度/存取周期$。
- 访问时间(存取时间)
一般用读出时间$T_A$以及写入时间$T_W$来描述。
$T_A$指的是从存储器接收到读指令开始到信息被送到数据线上所需的时间。
$T_W$指的是从存储器接收到写指令开始到信息被写入存储器中所需的时间。
- 存取周期($T_M$)
存取周期指存储器进行一次读写操作所需要的全部时间,也就是存储器进行连续读写操作所允许的最小时间间隔。它应该等于访问时间+下一次存取开始前所需要的附加时间。
存储器中由于读出放大器、驱动电路都有一段稳定恢复时间,读出后不能进行下一次访问。所以一般$T_M>T_A,T_M>T_W$。
- 存储器的带宽($B_M$)
存储器的带宽也称数据传输速率,表示存储器被连续访问时可以提供的数据传输速率,通常用每秒钟传输信息的位数/字节数来衡量。
3.1.3 存储器的层次化结构
存储器的速度越快往往容量越小,越靠近CPU。现代存储器往往采用层次化结构存储器构成,主要思想是上一层的存储器作为低一层存储器的高速缓存。
CPU执行指令时需要的操作数大部分都来自寄存器,如果需要向存储器中存取数据,先访问Cache;如果不在Cache则访问主存;如不在主存则访问硬盘。此时操作数从硬盘中读出送到主存,然后从主存送到Cache。
由此可知,在层次化结构存储器中数据一般只在相邻两层之间复制传送,而且总是从慢速存储器复制到快速存储器被使用,传送的单位是一个定长块。上一层的内容都只是下一层的内容的副本,即只是下一层内容的一部分。
从CPU的角度看,Cache-主存层的速度接近于Cache,容量和价位却接近主存,其他层亦是如此,解决了速度、容量、成本之间的矛盾。
主存和Cache之间的数据调动是由硬件自动完成的,对所有程序员都是透明的;主存和辅存之间的数据调动是由硬件和操作系统共同完成的,对应用程序员是透明的。
在主存-辅存层的不断发展中逐渐形成了虚拟存储系统,这个系统中程序员编址的地址范围与虚拟存储器的地址空间相对应,编程时可用的地址空间远大于主存空间。
3.2 主存储器
3.2.1 RAM的存储原理
- 存储元
存放一个二进制位的物理器件称为存储元
,它是存储器最基本的构件。地址相同的多个存储元构成一个存储单元。
选中某个存储单元时,实际上是通过字线来控制多个存储元,进而读出或写入数据。若干个存储单元的集合构成存储体
。
DRAM的工作原理
DRAM的每个存储元通常由1个电容和1个MOS管构成。当DRAM中某个电容存储的电荷达到或超过阈值时,该电容所在存储元表示1,否则表示0。
DRAM具有集成度高、价位低和功耗低等优点,但是DRAM比SRAM慢,而且必须定时刷新和读后再生,一般用于主存。
读出时,电容会流出电流,信号放大器通过检测电容的电压信息从而判断是0还是1。电容里的点被释放后还需要再次充电,这种读出叫破坏性读出
。破坏性读出后需要恢复被读出的电容上的电荷,这个过程叫再生
(或读后再生
)。
DRAM的刷新(重点)
由于电容会不断漏电,需要不断给它充电,这个过程叫“刷新
”,DRAM电容中的电荷周期一般为10-64ms,若不刷新则会丢失存储的数据。这也是叫DRAM的原因,因为要不断刷新。充电需要时间,因此速度会比SRA慢。
刷新过程和再生过程并不相同。刷新是以行为单位,逐行恢复数据的。而再生仅需恢复被读出的那些单元的数据。
DRAM的刷新以行为单位,具体过程为:(双译码结构)先对某一行的全体电容先读取一次数据再写入一次数据(假读
)。为确保数据不丢失,每一行的刷新时间间隔不会超过2ms。对同一行进行相邻两次刷新的时间间隔称为刷新周期
,可以看出刷新周期远远大于刷新一行的时间。刷新一行的时间一般等于存储时间。如果某个存储器由多个芯片构成,则构成存储器的所有芯片同时按行刷新。
刷新地址是由刷新地址计数器产生,而不是CPU发出,即刷新对CPU是透明的。
刷新地址计数器的位数与动态存储芯片内部的行结构有关,通常刷新操作由内存控制器负责。
例:如果某DRAM内部有4行,则刷新地址计数器至少为2位,每个刷新周期内该计数器的值从00到11循环一次。
刷新过程中,DRAM不能响应CPU的访问,因此CPU访问内存和内存控制器刷新操作存在内存争用问题。常见的解决方式有几种刷新、分散刷新、异步刷新三种。
例:某DRAM有128行*128列结构,读写周期(存储周期)$t_c=0.5us$,刷新间隔为2ms,因此2ms内应该完成所有128行的刷新。
- 集中刷新:在一个刷新周期内,利用一段固定时间,依次对存储器的所有行进行逐一再生,在此期间停止对存储器的读写操作,称为
死时间
,也称访存死区
。优点是读写操作期间不受刷新操作的影响,速度比较快。缺点是在死区时间内不能访问存储器,且芯片内部的行数越多,死区时间就越长。 - 分散刷新:将一个存储器系统的工作周期分为两部分:前半部分用于正常的读写操作,后半部分用于刷新。这种刷新方式增加了系统的存取周期,优点是没有死区,缺点是加长了系统的存取周期,且刷新过于频繁,严重影响系统的速度,不适用于高速存储器。
- 异步刷新:结合了上述两种方法,使得在一个刷新周期内每行仅刷新一次。将刷新周期除以行数,得到相邻两行之间刷新的时间间隔t,每隔t产生一次刷新请求。这样就让死时间的分布更加分散,避免让CPU连续等待过久。
DRAM芯片的读/写周期
读写周期时间表示DRAM芯片进行两次连续读/写操作时所必须间隔的时间。
$\overline{RAS}$为行选通信号
,上划线代表低电平有效,该信号低电平时声明当前地址线的信号为行地址。
$\overline{CAS}$为列选通信号
,低电平有效,声明当前地址信号为列地址。
第三行为地址线,负责先传输行地址再传输列地址。
$\overline{WE}$为读写控制信号,高电平时确定DRAM应该采取读操作,低电平时采取写操作。
第五行是数据线,负责传输已读出的数据或预写入的数据。
以读周期为例,CPU和主存间发送的信号必须满足一定的顺序关系。
- 在$\overline{RAS}$信号发出前,行地址必须送到芯片的地址输入端。
- $\overline{CAS}$信号的发出既要在$\overline{RAS}$信号发出后,也要在列地址送到地址线后。
- 在$\overline{CAS}$信号有效之前应使$\overline{WE}$信号设置为高电平(设置为读操作)。
- 每次读操作以后必须再生,恢复被破坏的数据。
在写周期中,$\overline{RAS}$和$\overline{CAS}$之间的关系和读周期相同,但是还有两点不同:
- 在$\overline{CAS}$信号有效之前应使$\overline{WE}$信号设置为低电平(设置为写操作)。
- 写数据在$\overline{CAS}$信号有效之前传输到数据线上。
SDRAM的特点
SDRAM
即同步DRAM
。现代计算机的主存通常基于SDRAM芯片。传统DRAM与CPU采用异步方式交换数据,SDRAM与CPU采用同步方式传输数据,同步于系统的时钟信号,并且以CPU-主存总线的最高速度运行,不需要插入等待状态。
其读写受系统时钟控制,将CPU发出的地址和控制信号锁存起来,CPU在读写完成之前可进行其他操作。SDRAM支持突发传输方式:
- 第一次存取时给出首地址,同一行的所有数据都被送到行缓冲器。
- 以后每个时钟都可以连续地从SDRAM输出一个数据。
行缓冲器
用来缓存指定行中整行的数据,其大小为$列数*存储单元位数$,通常用SRAM实现。此外,SDRAM内部的工作方式寄存器可以设置:
- 传输数据的长度(突发长度)。
- 收到读命令到开始传输数据的延迟时间。
SRAM的工作原理
SRAM的存储元是用双稳态触发器(包含6个MOS管)来记忆信息,两个稳定状态分别表示0和1。静态是指即使信息被读出后,它仍保持原状态且不需要再生,也不需要不断刷新。SRAM的存取速度快,但是集成度低,功耗大,价格贵,一般用于Cache。
DRAM VS SRAM
特征 | SRAM | DRAM |
---|---|---|
构成 | 双稳态触发器(包含6个MOS管) | 电容+MOS管 |
破坏性读出 | 否 | 是 |
需要刷新 | 不需要 | 需要 |
送行列地址 | 同时送 | 行列分开送(复用) |
易失性 | 是 | 是 |
再生 | 不需要 | 需要 |
是否行列地址复用 | 否 | 是 |
运行速度 | 快 | 慢 |
集成度 | 低 | 高 |
功耗 | 高 | 低 |
价格 | 高 | 低 |
主要用途 | 高速缓存 | 主存 |
存储器芯片的内部结构
存储器芯片由存储体(存储矩阵)、I/O读写电路、译码驱动电路(译码器、驱动器)和控制电路等部分组成,还与地址线、数据线、片选线和读写控制线相接。
- 存储矩阵是存储单元的集合,负责存储数据。
- 译码驱动电路和地址线相接,负责将CPU传来的地址信号翻译成特定存储单元的选择信号,选定某个存储单元。
- 读写电路与数据线相接,负责将待写入的数据写入存储矩阵,或从矩阵读出数据。
- 控制电路负责控制存储器进行读操作和写操作。
- 数据线是双向的,负责传输待读出的数据或待写入的数据。
- 地址线是单向的,负责将待访问的存储器地址传入译码器中。
- 读写控制线是单向的,负责传输CPU向存储器下达的读写命令。
- 片选线是单向的,负责选定需要访问的存储器芯片。
地址译码驱动方式有两种:
- 单译码法(线选法)。在这种方式中地址译码器只有一个,同一行中所有的存储单元的字线连接在一起,同一行的各单元构成一个字,同时被读出或写入。缺点是地址译码器的输出线数过多,n根地址引脚可以输出$2^n$个输出引脚,只适合容量小的静态存储器。
- 双译码法(重合法)。为了节省驱动电路和解决单译码法存在的缺陷,可以使用双译码法。地址译码器(译码驱动电路中)被分为行选择线X和列选择线Y。(X,Y)可以唯一确定一个存储单元,实数对中的X由行地址译码驱动来译码,Y由列地址译码驱动译码。n根输入引脚,输出只需要$2^{(n/2)+1}$个引脚,适合大容量的动态存储器(DRAM)。
DRAM一般使用行列地址复用技术,SRAM一般使用行列独立技术。
- 行列地址复用技术:使用双译码法分先后两次将存储矩阵的行地址和列地址传入译码驱动电路(DRAM采取地址复用技术),从而将地址线数量减半。DRAM的大小较SRAM大很多,引入行列地址复用技术能有效减少芯片引脚数目。
- 行列独立技术:一次性传递整个访问地址,地址线数量不减半。
单片存储芯片的存储容量有限,要获得一个大容量的存储器,通常需要将多片存储芯片组织起来,共同构成一个存储器。
3.2.2 ROM的存储原理
ROM的特点
ROM
和RAM
都是支持随机访问的存储器,ROM中一旦有了信息,就不能轻易改变,即使掉电也不会丢失。ROM有两个显著的优点:1.结构简单,位密度高;2.非易失性,可靠性高。
ROM的类型
根据制造工艺的不同,ROM可分为掩模式只读存储器
(MROM)、一次可编程只读存储器
(PROM),可擦除可编程只读存储器
(EPROM)、Flash存储器
和固态硬盘
(SSD,Solid State Drive)。
- 掩模式只读存储器
MROM的内容在芯片生产过程中直接写入,写入后任何人都无法改变。优点是可靠性高,集成度高,价格便宜;缺点是灵活性差。
- 一次可编程只读存储器
PROM可以实现一次性编程,允许用户写入程序,一旦写入就无法改变。
- 可擦除可编程只读存储器
EPROM不仅可以由用户写入信息,而且可以对其内容进行多次改写。但是它不能取代RAM,因为EPROM的编程次数有限,且写入时间过长。
- Flash存储器
Flash存储器又称闪存
,基于EPROM,具有非易失性,支持快速擦除和重写,写入之前必须先擦除。写的速度慢于读,例如U盘。
- 固态硬盘
SSD基于闪存
制成,由控制单元
和存储单元
(Flash芯片)组成。保留了Flash存储器长期保存信息、快速擦除和重写的特性,比传统硬盘读写速度快,功耗更低。代价是价格较高。
3.3 主存容量扩展以及并行技术
3.3.1 主存容量的扩展
主存与CPU的连接原理
- 主存通过数据总线、地址总线和控制总线与CPU连接。
- 数据总线的位数与工作频率的乘积正比于数据传输速率。
- 地址总线的位数决定了可寻址的最大内存空间。
- 控制总线指出总线周期的类型和本次输入/输出操作完成的时刻。
由于单个存储芯片的容量是有限的,在字数或字长方面需要扩充,一般采用位扩展
、字扩展
、字位同时扩展
等方法。
位扩展
位扩展又称为字长扩展
或数据总线扩展
,当存储芯片的数据总线位宽小于CPU数据总线位宽时,采用位扩展方式进行扩展。
位扩展的连接方式:各芯片的地址线、片选线和读写控制线与系统总线相应并联;各芯片的数据线单独引出,分别连接系统数据线。各芯片分时工作。
字扩展
字扩展也成为容量扩展
或地址总线扩展
。当存储芯片的字数不能满足存储器的要求时,可采用字扩展方式来扩展存储器。
字扩展的连接方式:各芯片地址线与系统地址线的低位对应相连;芯片的数据线和读写控制线与系统总线相应并联;由系统地址线的高位译码得到各芯片的片选信号。各芯片分时工作。
- 线选法
线选法用除片内寻址外的高位地址线直接连接至各个存储芯片的片选端,当某位地址线信息为0时,就选中与之对应的存储芯片。
每次寻址时片选地址先只能有一位有效,不允许同时有多位有效,这样才能保证每次只选中一个芯片。
采用线选法进行字扩展时:
优点:不需要地址译码器,线路简单。
缺点:地址空间不连续,选片的地址线必须分时为低电平,不能充分利用系统的存储器空间,造成地址资源的浪费。
- 译码片选法
译码片选法用除片内寻址外的高位地址线通过地址译码器
产生片选信号。若采用译码片选法,则仅需要高2位用于片选。
字位同时扩展
存储器的字数和字长均不能满足存储器的数据位和存储总容量的要求时,可以采用字位同时扩展。首先通过位扩展满足数据位的要求,再通过字扩展满足存储字数的要求。
3.3.2 并行主存系统
由于CPU速度快,主存慢,CPU需要等待主存,因此要提高主存的速度。
提高主存的速度可从三个方面考虑。
- 提高DRAM芯片本身的速度。
- 采用并行结构技术,如双端口存储器,多模块存储器。
- 在CPU和主存之间加入高速缓冲存储器。
双端口存储器
双端口存储器
在一个存储器中提供两组独立的读写控制电路和两个读写端口(端口其实就是寄存器),可以同时提供两个数据的并行读写。
- 每个读写口都有一套独立的地址缓存器和译码电路,两套电路并行独立工作。
- A、B两个端口地址不相同时,可以向存储体一次读写两个单元的内容。
A、B两个端口地址相同时,发生冲突,可以按照特定的优先顺序选择其中一个端口进行读写。
并行访问存储器
主板上有多个内存条插槽,多个内存条通过总线和CPU连接。通常由多条存储器总线同时传输数据。常见的双通道内存插槽,支持两条总线同时传输数据,其传输带宽是单通道的两倍。我们可以把内存条称为一个主存模块
。
常规的主存是单体单字存储器
,只包含一个存储体。目前高速的计算机普遍采用并行主存系统,即多个并行工作的存储器共有一套地址寄存器和译码电路,按同一地址并行地访问各自的对应单元。
优点:并行访问存储器按地址在一个存取周期内可读出n*w位的指令和数据,使主存带宽提升n倍。
缺点:指令和数据在主存中必须连续存放,一旦遇到转移指令,或者操作数不能连续存放,这种方法的效果就不明显了。
目前在计算机中常见的多通道内存技术就是采用单体多字,常见的有双通道、三通道、四通道技术。
交叉访问存储器(重点)
交叉访问存储器
中有多个容量相同的存储模块(存储体)。各存储模块都有独立的地址寄存器、读写电路和数据寄存器。这就是多体系统
。各个存储体既能并行工作,又能交叉工作。
根据多个模块编址方式的不同,其组织方式又分为高位多体交叉
和低位多体交叉
两种。
- 高位多体交叉(顺序方式)
高位多体交叉的主要目的是扩充存储器的容量。类似线选法字扩展,高位地址译码产生片选信号,选择不同的存储模块;低位地址直接选择一个存储模块内的不同存储单元。
高位交叉方式中不同存储模块的地址区间不同,是按顺序分配的地址。高位多体交叉又称为顺序编址模式
。高位交叉方式下访问一个连续主存块时,CPU总是顺序访问存储模块,各个模块之间不能被并行访问,因此不能提高存储器的吞吐率。
模块内的地址是连续的,存取方式仍旧是串行读取,因此仍然是顺序存储器。
- 低位交叉编址(交叉方式)(重点)
低位交叉方式下,用低位地址译码进行片选,用高位地址选择存储模块内的不同存储单元。
将M个有序地址分配给M个存储模块后,再将下面的M个地址一次分配给M个存储模块,直到将全部线性地址分配完。这种编址方式被称为交叉编址模式
。采用这种编址方式的存储器称为交叉存储器
。
低位交叉方式有如下特点:
- 相邻的地址处在不同存储体中,同一存储体的地址不相邻。
- 以模4为例,低位交叉方式下,4个存储体编址序列如下表:
多体交叉存储器的作用(低位交叉)
CPU访存的原理
CPU通过存储器总线读取一个数据的过程为:
- CPU发送数据地址和读命令,花费的时间为$T_1$。
- 存储器接收到地址和命令后,准备数据并将数据送到数据总线上,花费的时间为$T_2$。
- 总线上传输数据,花费的时间为$T_3$。
访问时间一般用读出时间$T_A$和写出时间$T_W$来描述,$T_A$是指从存储器接收到读命令开始至信息被送到数据线上所需的时间。因此CPU进行一次数据读取的总时间应该是$T_1+T_2+T_3$,其中$T_2=T_A$。
有的题目不会给出$T_A$,只会给出存储周期,这个时候只能把存储周期看作是$T_2$。
高位交叉CPU访存过程
低位交叉CPU访存过程
在高位交叉编址下,读出一个数据的平均时间为$nT/n=T$。
在低位交叉编制下,读出一个数据的平均时间为$[T+(n-1)r]/n$。
当n接近于$\infty$时,此时极限值为r,即每个数据的读出时间平均为r。
若T=4r,则将数据的读取时间缩短为原来的四分之一。
3.3.3 启动方式
交叉编址多模块存储器可以采用轮流启动
和同时启动
两种方式。假设存储模块的存储周期是T,总线传输周期为r,交叉模块数为m(通常为2的幂次方)。
轮流启动
如果每个存储模块一次读写的位数正好等于系统总线中的数据位数(总线传输单位),则采用轮流启动
方式,轮流启动下,每隔r启动一个模块进行读写。要实现流水线方式存取,应当满足:$T<=mr$,一般取$T=mr$。
- 每个存储单体的存储周期仍然为T。
- 经过一个存储周期T,每隔r时间延迟可传送一个新的数据。
- 连续读取n个字所需的时间为$T+(n-1)r$。
- 流水线稳定时,一个存储周期内向CPU提供了4个存储字。
同时启动
若所有模块一次并行读/写的总位数正好等于数据总线位数,则可以同时启动所有模块进行读/写。
假设每个模块一次读写的位数为16位,模块数=4,数据总线的位数为64位,此时4个模块提供64位,正好构成一个存储字,因此应该同时启动4个模块进行并行读写。
3.3.4 字位扩展与并行技术总结
3.4 外部存储器
3.4.1 磁盘存储器
磁盘存储器
简称磁盘
,以磁盘为存储介质,可以存储大量的二进制数据。早期使用的是软磁盘(软盘),现在常用的是硬磁盘(硬盘)。
优点:
- 存储容量大,位价格低。
- 记录介质可重复使用。
- 记录信息可长期保存而不丢失,具有非易失性。
- 非破坏性读出,读出时不需要再生。
缺点:存取速度慢,机械结构复杂,对工作环境要求较高。
磁盘设备的组成
磁盘存储器由磁盘驱动器
、磁盘控制器
、磁头
、盘片
等组成。
- 盘片
一个磁盘存储器拥有一个或多个盘片,每个盘片都有两个盘面
。
每个盘面由多个圆环组成,圆环上均匀分布着磁介质(用来存储0/1),每个圆环形成一个盘面的磁道,相邻磁道的物理距离被称为道距
。
为了方便查找数据在磁道中的位置,每个磁道还被分成多个扇区
,磁盘的读取以扇区为单位。扇区之间也有扇区间隙
每个磁道存储的数据量相同。
通常每个磁道拥有相同数量的扇区,每个扇区存放存储容量相同的数据。
磁盘读写过程
盘面上下两面各有一个磁头
,每个磁头对应一个盘面。
磁头安装在磁头臂
上,磁头臂可以带动磁头进行朝内朝外的移动,继而访问不同的磁道。
一个磁头臂上有多个磁头,当磁头臂移动时,多个磁头会同时移动。因此各个磁头始终指向不同盘面的同一磁道。
多个磁道号相同的磁道,共同构成一个柱面
,柱面号即为磁道号。
3.4.2 磁盘存储器的性能指标
记录密度
记录密度是指盘片单位面积上记录的二进制信息量,通常以道密度
、位密度
、面密度
表示。
道密度
是沿磁盘半径方向单位长度上的磁道数。
位密度
是磁道单位长度上能记录的二进制代码位数。
面密度
是位密度和道密度的乘积。
磁盘的容量
磁盘容量有非格式化容量
和格式化容量
之分。
非格式化容量
指的是磁记录表面可利用的磁化单元总数。(磁化单元
是存储数据的最小物理单位,每个磁化单元可以代表一个二进制值,0或1)
$非格式化容量=柱面数盘面数每条磁道的磁化单元数$
格式化容量
指的是按照某种特定的格式所能存储信息的总量。(扇区需要地址、校验等信息)
$格式化容量=记录面数柱面数每道扇区数*每个扇区的容量$
格式化后的容量比非格式化的容量要小。
存取时间
存取时间由寻道时间
、旋转延迟时间
、传输时间
三部分构成。
寻道时间
是磁头移动到目的磁道的时间。
旋转延迟时间
是磁头定位到要读写的扇区的时间。
传输时间
是传输数据所花费的时间。
因为寻道和找扇区的距离远近不一,通常寻道时间和旋转延迟时间取平均值。平均寻道时间取从最外道到最内道时间的一半,平均旋转延迟时间取旋转半周的时间。
数据传输速率
磁盘存储器在单位时间内向主机传送数据的字节数,称为数据传输速率
。
假设磁盘转数位r转/秒,每条磁道容量位N字节,则数据传输速率$D_r=rN$。
3.4.3 磁盘其他部分
- 磁盘控制器
磁盘控制器
是CPU(通过总线连接)与磁盘驱动器之间的接口。由于CPU运行速度比磁盘运行速度快,磁盘控制器负责接受CPU发来的命令并转换成磁盘驱动器的控制命令,并实现CPU和驱动器之间的数据格式转换。
- 磁盘驱动器
负责接收磁盘控制器的控制命令,并控制磁头组件和盘片组件进行读写操作。
- 磁盘高速缓存
在内存开辟一部分区域,用于缓冲将被送到磁盘上的数据。
优点:写磁盘时是按“簇”进行的,可以避免频繁地用小块数据写;有些中间结果在写回磁盘之前可以被快速地再次使用。
CPU大哥-控制器话事人-驱动器操作工。
磁盘存储器的地址结构
可以将磁盘分为多个磁盘组
,每个磁盘组包含多个盘面。
磁盘在寻址时应该:
- 先确定访问哪个磁盘组
- 确定访问磁盘组中的哪个柱面
- 确定应该访问的盘面
- 确定扇区
假设每个磁道有16个扇区,8个盘面,每个磁盘128个磁道,一共4个磁盘组,则:
磁盘地址的低4位为扇区号,相邻的高3位为盘面号,再高的7位为柱面号,最高的2位为磁盘组号。
倘若不考虑分为磁盘组则如下如图所示:
假设磁盘有16个盘面,每个盘面128个磁道,每个磁道分为16个扇区,则每个扇区地址要用16位二进制代码。
磁盘阵列
磁盘阵列
(RAID,Redundant Arrays of Independent Disks),即独立磁盘构成具有冗余能力的阵列,其实是多个独立的磁盘组合形成一个大的磁盘系统,从而实现比单块磁盘更好的存储性能和更高的可靠性。
磁盘阵列分为RAID0-RAID5,代表架构和功能的不同。
- RAID0
RAID0是一种简单的、无数据校验的磁盘阵列,实际上不是一种真正的RAID,并不提供冗余策略。
RAID0把连续多个数据块交替地存放在不同物理磁盘的扇区中。几个磁盘交叉并行读写,即条带化技术
,这样不仅扩大了存储容量,还提高了磁盘存取速度,但是没有容错能力。
- RAID1
镜像存储磁盘阵列
:RAID1是单位成本最高的一种方式。在往磁盘写数据的时候,将同一份数据无差别地写两份到磁盘,分别写到工作磁盘和镜像磁盘。
- RAID2
采用纠错的带海明码校验的磁盘阵列:RAID2使用海明码来提供错误检查及恢复。
- RAID3
位奇偶校验码磁盘阵列:只能查错不能纠错。
- RAID4
块奇偶校验码磁盘阵列:和RAID3相似,它对数据的访问是按数据块进行的,也就是按磁盘进行的,每次一个盘。
- RAID5
分布式(无独立校验)奇偶校验的独立磁盘结构。
3.4.4 固态硬盘
基本结构与工作原理
固态硬盘是闪存技术的存储器,与U盘没有本质差别,只是容量更大,存取性能更好。一个SSD由一个或多个闪存芯片
和闪存翻译层
组成。
闪存芯片替代传统旋转盘中的机械驱动器;闪存翻译层将来自CPU的逻辑块读写请求翻译成对物理设备的读写信号,代替了磁盘控制器的角色。
一个闪存由n个块
组成,每块由P页
组成。通常页的大小为512B-4KB,每块由32-128页组成,块的大小为16KB-512KB。固态硬盘以页位单位读写数据,但写入比读取要慢。这是因为SSD在写入时需要擦除(以块为单位),同时如果试图对已经装有数据的页写入,还需要将该页所在块中所有已写入数据的页复制到新块中,才能对该页进行写入。
固态硬盘相比于机械硬盘:
优点:启动快、读取时间快、抗摔性能强。
缺点:一个块的写入次数不能过多(一般不超过10万次),否则该块会因为磨损而无法再次写入。
磨损均衡技术
磨损均衡
大致分为动态磨损均衡
和静态磨损均衡
两种。
- 动态磨损均衡:写入数据时自动选择较新的闪存块。
- 静态磨损均衡:SSD检测并自动进行数据分配,让老闪存块承担无需写数据的存储任务,让较新的闪存块腾出空间,平常的读写操作在较新的闪存块中进行。
还可以采用CF-LRU(Clean-First LRU)算法进行优化,类似页面置换算法。
3.5 高速缓冲存储器
3.5.1 程序访问的局部性原理
Cache是一种小容量高速缓冲存储器,由SRAM组成,直接制作在CPU芯片内,速度几乎与CPU一样快。主存中被频繁访问的程序和数据总是会被复制到Cache中。
由于程序访问的局部性,CPU能直接从Cache中取得指令和数据而不用访问主存。
程序访问的局部性原理
解释了为什么计算机程序倾向于频繁访问一小部分数据和指令,可以进一步分为两种类型:时间局部性
和空间局部性
。
- 时间局部性:某个内容被访问后可能不久后会被再次访问。
空间局部性:某个内容被访问后,其相近的内容可能被访问。
对于指令而言,指令中存在大量的循环结构,导致同一条指令短时间内可能会多次运行,所以指令有时间局部性。同时指令往往是顺序执行,可能执行完第x条指令就去执行第x+1条指令了,所以指令有空间局部性。
对于数据而言,同一个变量可能短时间内多次被访问,所以数据有时间局部性。许多数据常以数组等连续结构存储,放在相邻的位置里,常在一段时间内被顺序访问,所以这类数据具有空间局部性。
由于程序访问的局部性,程序运行时,频繁访问的程序和数据其实集中在主存的某几块区域内,可以把这几块区域的指令和数据都复制到cache中,这样CPU需要访存的时候可以先去cache里看看。
3.5.2 主存块以及Cache块
为了方便Cache和主存交换信息,Cache和主存都被划分为相等的区域。
主存中的区域称为块
,也称为主存块
,它是Cache和主存之间的信息交换单位。
Cache中存放一个主存块的区域称为行
或者槽
(也可称为Cache块
)。
因此,主存块大小等于Cache行中数据区大小。
将主存分为多个主存块后,主存地址可以划分为两部分。
高位地址 | 地位地址 |
---|---|
块号 | 块内地址 |
把Cache划分为多个Cache块后Cache地址也可已划分为上表的两部分。
Cache块的有效位
为了防止主存内容改变时能发现Cache块和主存块中内容不同的错误,每个Cache行需要一个有效位
,有效位为1表示该Cache行的信息有效,可以访问,否则无效。
可以通过将有效位清零来淘汰某Cache行的主存块数据;装入一个新的主存块时再将有效位置1。
3.5.3 Cache的基本工作原理
CPU在Cache中的访问过程
CPU需要从主存取指令或读数据时,先访问Cache。
如果有,直接从Cache中取,不用访问主存,即Cache命中
。
如果没有,就从主存中把当前访问信息所在的一个主存块复制到Cache中,即Cache未命中
。因此,Cache中的内容是主存中部分内容的副本。
完整的访存过程包括多个工作:判断信息是否在Cache,从Cache取信息,从主存取一个主存块到Cache,在对应Cache行满的情况下替换Cache中的信息。
这些工作要求在一条指令执行过程中完成,因此只能由硬件来实现。
Cache对程序员来说是透明的,程序员在编程时不需要考虑信息存放在主存还是在Cache。
Cache-主存层的平均访问时间
在访存过程中需要判断访问信息是否在Cache中。
如果Cache命中,命中率为p,等于命中次数与访问总次数之比。
若未命中,其概率称为缺失率
,等于未命中次数与访问总次数之比。
命中时,CPU在Cache中直接存取信息,时间开销为Cache访问时间
$T_c$,称为命中时间
。
缺失时,需要从主存读取一个主存块送入Cache,并同时将所需信息送入CPU,时间开销为主存访问时间$T_m$和Cache访问时间$T_c$之和,通常把$T_m$称为缺失损失
。
CPU在Cache-主存层的平均访问时间为:$T=pT_c+(1-p)(T_m+T_c)=T_c+(1-p)*T_m$
由于程序访问的局部性原理,Cache的命中率很高,接近于1。因此虽然$T_m>T_c$,但最终的平均访问时间仍然接近Cache的访问时间。
实现Cache需要解决以下关键问题:
- 数据查找。如何判断数据是否在Cache中。
- 地址映射。主存块如何存放在Cache中,如何将主存地址转换为Cache地址。
- 替换策略。Cache满后,使用何种策略对Cache块进行替换或淘汰。
- 写入策略。如何既保证主存块和Cache块的数据一致性,又尽量提升效率。
Cache行和主存块之间的映射方式
主存块和Cache行之间必须遵守一定的映射规则。
主存块和Cache行之间有以下3种映射方式:
全相联映射
:每个主存块可以复制到Cache的任意行中,访存时需要把Cache的所有行全找一遍。
直接映射
:每个主存块映射到Cache的特定行中,访存时只需要查看某个特定行。
组相联映射
:把Cache分为多个组,每个组里有多个行,主存块可以放到特定组的任意行中,访存时查看特定组的所有行。
- 直接映射
把主存的每一块映射到固定的一个Cache行中,也称为模映射
。
$Cache行号=主存块号\space mod \space Cache行数 = 主存块号 \% Cache行数$
也就是地址x/2->得到主存块号->对主存块号%2->得到Cache块号。
由此可知主存地址被分为3个字段:
主存地址剩下的高位地址部分被称为标记
,作为主存块和Cache块是否匹配的验证信息。实际上Cache还有标记位。
假设CPU访问地址为1111 1010B,访存过程如下:
- 根据访存地址中间的两位(10->Cache块2),找到对应的Cache行。
- 将对应Cache行中的标记和主存高4位标记进行比较。
- 如果相等且有效位为1,则Cache命中,此时根据主存地址低位的块内地址在对应的Cache行存取信息。
- 如果不相等或有效位为0,则未命中,此时从主存读出改地址所在块的信息送到对应的Cache行中,将有效位置1,并将标记设置为地址中的高4位,同时将该地址中的内容送CPU。
直接映射实现简单,缺点在于不够灵活,块冲突概率最高,空间利用率最低。
- 全相联映射
一个主存块可以装入Cache任意一块中。只要有空闲Cache块,就不会发生冲突,因此块冲突概率低于直接映射。
访存过程:
将主存地址的高位标记与Cache各行的标记进行比较:
- 若有一个相等且对应有效位为1,则命中,此时根据块内地址从该Cache行中取出信息。
- 若都不相等,则不命中,此时从主存中读出该地址所在块的信息送到Cache任意一个空闲行中,将有效位置1,并设置标记,同时将该地址的内容送CPU。
优点:Cache块的冲突概率低,空间利用率高,命中率高。
缺点:标记的比较速度比较慢,实现成本较高,通常需要按内容寻址的相联存储器。
通常为每个Cache行都设置一个比较器
,比较器位数等于标记字段的位数。访存时,根据标记字段的内容来访问Cache行的主存块,查找过程是“按内容访问”的存取方式,所以是一种相联存储器。这种方式的时间开销和空间开销都较大,不适合大容量Cache。
- 组相联映射
将Cache分成Q个大小相等的组,每个主存块可以装入固定组中的特定一行。组间采用直接映射,组内采用全相联映射。若为r路,称为r路组相联。$Cache行数=组数*路数$。
可以看出,Q=1时变为全相联映射,Q=Cache行数时变为直接映射。
组相联的路数越大,即每组Cache行的数量越大,发生冲突的概率越低,但电路也越复杂。选择合适的路数可以使组相联映射的成本接近直接映射,而性能接近全相联映射。
访存过程:
- 根据访存地址中间的组号找到对应的Cache组。
- 将对应Cache组中的每个行的标记与主存地址的高位标记进行比较。
- 若有一个相等且有效位为1,则Cache命中,此时根据主存地址的块内地址在对应Cache行存取信息。
- 若都不相等或有效位为0,则未命中,此时从主存中读出该地址所在块的信息送到对应Cache组的任意一个空闲行中,将有效位置1,并设置标记,同时将该地址中的内容送CPU。
对比如下:
比较器个数
假设有n个Cache行:
全相联映射下,每块可以映射到所有Cache行,所以需要设置n个比较器。
直接映射因为每块只能映射到唯一的Cache行,只需要设置1个比较器。
组相联映射需要在对应分组中与r个Cache行进行比较,需要设置r个比较器。
3.5.4 Cache中主存块的替换算法
由于Cache的容量远小于主存的容量,经常要把某一Cache块替换出去,腾出空间新的主存块,这个过程称为替换
。
对于直接映射
,一旦发生替换,则被替换块唯一;对于全相联映射
和组相联映射
,则需要在若干块中选择合适的一块替换出去。
替换块的策略叫替换策略
或替换算法
。替换操作完全是通过硬件方式实现的。
常见的替换算法有随机算法
(RAND)、先进先出算法
(FIFO)、近期最少使用算法
(LRU)和最不经常使用算法
(LFU)。
随机算法
随机地确定替换的Cache行。实现比较简单,但是未根据程序访问的局部性原理,命中率可能较低。
先进先出算法
选择最早调入的Cache行进行替换。实现也比较简单,但是也未根据程序访问的局部性原理,因为最早进入的主存块可能是经常要用的。
近期最少使用算法
依据程序访问的局部性原理,选择近期内长久未访问过的Cache行进行替换,平均命中率比FIFO高,是堆栈类算法。
LRU算法对每个Cache行设置一个计数器(也称为LRU计数位),用计数值来记录主存块的使用情况,根据计数值选择淘汰某个块。
组相联映射下,计数值的位数和Cache组大小有关,2路时有1位LRU位,4路时有2位LRU位,即$\log_2路数$。
全相联映射下,计数值的位数与Cache行数有关,即$\log_2行数$。
上图计数器的变化规则:
- 命中时,所命中的行计数器清零,比其低的计数器+1,其余不变。
- 未命中且还有空闲行时,新装入的行的计数器置0,其余的全+1。
- 未命中且无空闲行时,计数值为3的行的信息块被替换,新装入的行的计数器置0,其余全+1。
当集中访问的存储区超过Cache组的大小时,命中率可能变的很低,这种现象称为抖动
。
最不经常使用算法
将一段时间内被访问次数最少的Cache行换出(频次)。
每行设置一个计数器,新行装入后从0开始计数,每访问一次,被访问的行计数器+1,需要替换时比较各特定行的计数值,将计数值最小的行换出。如果有多个计数值最小的行,可按行号递增或FIFO策略进行选择。
3.5.5 Cache的一致性问题
Cache的内容是主存内容的副本,但是CPU对Cache的写操作可能会导致Cache与主存内容不一致,引发一致性问题。解决Cache一致性问题的关键是处理好写操作。对于Cache的写操作命中,有两种处理方法:
全写法
全写法
又称为直写法
。写操作时,若写命中,则同时写Cache和主存。
优点是较为简单,能随时保持一致性。
缺点是增加了访存次数,降低了Cache的效率。
此外需要引入写缓冲
,CPU在数据写入Cache的同时也写入写缓冲,然后由写缓冲将数据写回主存。写缓冲是一个FIFO队列,将对主存的写请求排成队列。当写请求过多时可能会引发写缓冲的溢出。
写回法
写回法
也称回写法
。写操作中若写命中,则信息只被写入Cache而不写入主存。直到该Cache被替换出去,才将数据写回主存。这种方法有潜在的数据不一致性,但减少了访存次数,提升了效率。
采取写回法的Cache应给每个Cache块附设一个1bit的脏位
(也叫修改位
),刚载入的Cache块其脏位设为0,当CPU修改该Cache块后脏位改成1。当Cache块替换出去时,若脏位为1,则需要写回主存。若修改位为0,说明该Cache块从未修改过,无需写回主存。
写回法可以提高系统的性能,减少写操作的次数,但是实现方法也更复杂。
写分配法
全写法和回写法都对应于Cache写命中的情况,即要修改的块在Cache中。
对于Cache写操作未命中,也有两种情况。
写分配法
是在写回主存后,把写入过的主存块调入Cache中(写完就分配给Cache)。调入过程会带来时间开销,但是更好地遵循了程序访问的局部性原理,一般与写回法相结合使用。
非写分配法
非写分配法
是在写回主存后,不把写入过的主存块调入Cache中(写完不分配给Cache)。节约了调入主存块引发的时间开销,但是不遵循程序的局部性原理,一般与全写法相结合使用。
3.5.6 Cache的分离与多级Cache
Cache分离
Cache刚出现时,指令和数据都存放在其中,称为统一Cache
。后来计算机系统结构采用了新技术,需要将指令Cache
和数据Cache
分开设计,出现来分离或独立Cache结构。
统一Cache的优点是设计和实现简单,但是执行部件存取数据时,指令预取部件又要从同一Cache读指令,两者会发生冲突。采用独立Cache结构可以解决这个问题。此外指令Cache通常比数据Cache有更好的空间局部性,因此两者分离后还可以根据自身特点进一步优化。
多级Cache
将Cache和处理器集成在同一芯片内,这个Cache称为第一级Cache
(L1)。由于L1在CPU芯片内,因此减少了片外总线的访问,加快了存取速度,提高了系统性能。
L1的容量通常较小,如果CPU要访问的数据不在L1内,就要通过总线访问主存。而主存和总线的访问速度较慢,容易影响系统的响应速度。
因此在CPU芯片外与主存之间再设置一个Cache,称为第二级Cache
(L2),L2比L1要大。L1和L2之间、L2和主存之间可以采用不同的写策略,例如L1-L2采用全写法,L2-主存采用写回法。
3.6 虚拟存储器
详见操作系统。