计算机组成原理——存储器(Memory)

存储器

  • 存储器的基本介绍
      • 存储器分类方式1(按照存储介质不同)
        • 半导体存储器
        • 磁表面存储器
        • 磁芯存储器
        • 光盘存储器
      • 存储器分类方式2(按照存取方式不同)
        • 随机存取存储器(RAM,Random Access Memory)
        • 只读存储器(ROM,Read Only Memory)
        • 串行访问存储器
      • 存储器分类方式3(按照在计算机中的作用不同)
        • 缓冲存储器
          • 缓存Cache和缓冲区buffer的区别
        • 主存储器
        • 闪速存储器(Flash Memory)
        • 辅助存储器
      • 存储器的层次结构
      • 存储器的存储层次
        • 1、缓存-主存
        • 2、主存-辅存
        • 虚拟存储系统(Virtual Memory,VM)
  • 主存储器
    • 主存储器的基本介绍
      • 主存储器内部组成的细化
      • 主存储器与CPU的联系
      • 主存储器中存储单元地址编号的分配方式
      • 主存的技术指标
        • 存储容量
        • 存储速度
    • 半导体存储芯片
      • 半导体存储芯片的基本结构
        • 存储矩阵
        • 译码驱动
        • 读/写电路
        • 总线
      • 译码驱动方式(选中芯片中某一个存储单元)
        • 线选法
        • 重合法
    • 随机存储器(RAM)
      • 静态RAM(SRAM)
        • 静态RAM基本单元电路
      • 动态RAM(DRAM)
        • 动态RAM基本单元电路
        • 动态RAM的刷新
      • 静态RAM(SRAM)和动态RAM(DRAM)的比较
    • 只读存储器
      • 掩模ROM
      • PROM
      • EPROM以及EEPROM
    • 存储器与CPU的连接
      • 扩展存储容量时的局部连接
        • 位扩展
        • 字扩展
        • 字、位扩展
      • 存储器与CPU的整体连接
        • 芯片地址线的连接
        • 芯片数据线的连接
        • 芯片控制线的连接(主要是片选线)
        • 存储芯片型号以及数量的确定
        • 存储器与CPU的整体连接的例题
    • 提高访存速度的措施
      • 主存的结构
        • 单体多字结构
        • 多体并行系统
    • 存储器的校验(使用汉明码进行纠错)
      • 基本介绍
        • 纠错理论
        • 汉明码
        • 汉明码的构造
      • 汉明码的纠错
      • 汉明码案例(构造+纠错)
      • 高性能存储芯片
        • SDRAM
        • RDRAM
        • CDRAM
  • 高速缓存存储器Cache
    • 未加入Cache之前,存储系统面临的问题
    • Cache的工作原理
      • Cache - 主存存储空间
      • Cache效率
      • Cache的基本结构
      • 存在Cache参与的内存读操作过程
      • 存在Cache参与的内存写操作过程
    • Cache的改进
      • 单一缓存和两级缓存
      • 统一缓存和分立缓存
    • Cache的主存地址映射
      • 直接映射(一种完全固定的映射关系)
      • 全相联映射(灵活性大的映射关系)
      • 组相联映射(上述两种映射方式的折中)
    • Cache的替换策略
      • 替换
      • 替换策略
  • 辅助存储器(还未补全,尽请期待)
    • 磁表面存储器
    • 硬磁盘存储器

存储器的基本介绍

存储器是计算机系统中的核心部件之一,用来存放程序和数据。有了存储器,计算机才具有记忆信息的功能,才能把计算机要执行的程序、要处理的数据以及处理的结果存储在计算机中

存储器分类方式1(按照存储介质不同)

半导体存储器

由半导体器件组成的存储器,当电源消失时,所存储信息随之消失,为一种易失性存储器

  • 半导体存储器分类(按照组成材料不同)

    • 双极型(TTL)半导体存储器:工作速度快,与CPU处在同一量级,但是集成度低、功耗大、价格偏高

    • MOS半导体存储器:高集成度,制造简单,价格低廉,功耗小,但是速度较双极型器件慢

磁表面存储器

在金属或塑料基体的表面涂上一层磁性材料作为记录介质,工作时磁层随载体高速运转,磁头在磁层上进行读写操作,按照剩磁状态的不同而区分"0"和"1",具有非易失的特点

  • 磁表面存储器分类(按照载磁体形状不同)

    • 磁盘

    • 磁带

    • 磁鼓(已经基本不使用了)

磁芯存储器

由硬磁材料做出的环状元件,在磁芯中穿有驱动线(通电流)和读出线,这样就可以进行读/写操作,磁芯为磁性材料,所以也是一种非易失的永久记忆存储器

由于体积过大,工艺复杂,功耗大,于是已经基本不使用了

光盘存储器

应用激光在记录介质(磁光材料)上进行读/写的存储器,具有非易失性的特点

存储器分类方式2(按照存取方式不同)

随机存取存储器(RAM,Random Access Memory)

也被称为随机存储器或者读写存储器,存取时间和存储单元的物理地址无关,为一种可读/写存储器,在存储器的任何一个存储单元的内容都可以随机存取,存取的时间和存储单元的物理位置无关(计算机的主存都采用这种随机存储器。一般的RAM芯片,关闭电源以后所存信息将全部丢失,故RAM常用来暂存运行的程序和数据。高速缓冲存储器Cache就是使用高速的静态RAM组成的小容量存储器

  • 随机存储器分类(按照存储原理的不同)
    • 静态RAM:以触发器原理寄存信息
    • 动态RAM:以电容充放点原理寄存信息
只读存储器(ROM,Read Only Memory)

早期的ROM因为技术不成熟所以无法擦写,出厂后就只能读数据,所以叫只读存储器,即一但存储了原始信息以后,在程序执行的过程中,只能将内部信息读出,无法随意改变原始信息。掉电以后所存信息不会丢失,故ROM通常将其用来存放固定不变的程序、常数、汉字字库,甚至用来进行操作系统的固化,ROM的内容是由生产厂家或者用户使用专用设备写入固化的。存数据的时间和存储单元的物理位置无关。只读存储器和随机存储器可共同作为主存的一部分,统一构成主存的地址域

硬盘和ROM的关系
由于ROM和硬盘都可以存储数据而且断电不会丢失,而且都广泛运用于电子产品中,所以很容易对两者产生混淆,这里进行一个大概的区分:硬盘分为两种,一种是机械硬盘(即磁盘HDD),一种是固态硬盘(SSD),机械硬盘和ROM没什么关系,但是固态硬盘用到的存储颗粒基于NAND FLASH闪存技术,该技术ROM技术发展的产物,所以说硬盘和ROM还是多多少少有些关系的,但不能说ROM就是硬盘

  • 只读存储器分类(根据用户需求不同而制造的不同只读存储器)
    • 掩模型只读存储器(MROM)
    • 可编程只读存储器(PROM)
    • 可擦除可编程只读存储器(EPROM)
    • 用电可擦除可编程只读存储器(EEPROM)
串行访问存储器

对存储单元进行读/写操作时,需要按照存储单元的物理位置的先后顺序寻找地址,根据信息所在物理位置的不同,存取时间会有所差异,即存取的时间和存储单元的物理地址相关

  • 串行访问存储器分类(根据访问数据的方式不同)
    • 顺序存取存储器:无论信息处在哪里,读/写必须从其介质的始端开始顺序访问,比如,磁带存储器的读/写过程
    • 直接存取存储器:整个读/写过程的前段为直接访问,后段为顺序访问,比如对磁盘进行读/写时,首先直接指出该存储器中的某一个区域(即磁道),然后再开始进行顺序访问

存储器分类方式3(按照在计算机中的作用不同)

缓冲存储器

用在两个速度不同的部件之间,比如CPU和主存之间实现二者速度的弥补,起到一个缓冲作用

一个熟悉的缓冲存储器就是高速缓存存储器Cache(一般使用静态RAM构成),速度高于主存

缓存Cache和缓冲区buffer的区别

1、缓冲区属于内存空间,是内存空间的一部分。我们在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据(就像人落地的时候,需要进行一个缓冲一样,数据的传递也需要一个缓冲),然后我们把这部分预留的空间就叫做缓冲区

buffer的全称其实为buffer cache,偏重于写,一般被称为写缓存write cache

  • 在没有加入缓冲区概念的时候,应用程序都是直接将内存中的数据传递给硬盘空间,但是由于内存相对于硬盘来说,速度极快,这样整体数据传递的速率就会因为硬盘速率低而过慢,导致内存中的应用程序效率过低

  • 在加入缓冲区的概念后,应用程序可以先将数据交给同在内存中的缓冲区,然后就可以执行其他任务(由于同在内存中,所以这个数据传递过程是极快的),在缓冲区中将要写入硬盘的数据暂存下来后再将缓冲区中的数据传递给硬盘空间,等缓冲区的数据取完后再次进行缓冲区的数据填充,这样就可以减少磁盘的读写次数,所以应用缓冲区可大大提高计算机的运行速度(比如原来是每秒要写100次硬盘,对系统冲击很大,此时用缓冲区将数据暂存起来,就会变成每10秒写一次硬盘,对系统的冲击就很小,写入效率也高了)

2、CPU中的Cache的中文名称是高速缓冲存储器。根据程序的局部性原理,当计算机执行程序时,数据与地址管理部件会预测可能要用到的数据和指令,并将这些数据和指令预先从内存中读出送到Cache。一旦需要时,先检查Cache,若有就从Cache中读取,若无再访问内存。Cache就是用来解决CPU与内存之间速度不匹配的问题,避免内存与辅助内存频繁存取数据,这样就提高了系统的执行效率

cache偏重于读,一般被称为读缓存read cache

主存储器

可以和CPU直接交换信息

闪速存储器(Flash Memory)

为半导体存储器,速度高于磁盘,低于主存,可以在主存和辅存之间实现二者速度的弥补,起缓冲作用,U盘就是使用闪速存储器制作的,闪速存储器可以在一些高性能计算机中作为硬盘

实际上,闪速存储器是在只读存储器EPROM和EEPROM的工艺基础上产生的一种新型,可靠性更高的可擦非易失性存储器,具有整片擦除的特点,对于需要周期性修改存储信息的应用场合,闪速存储器为一个极其理想的器件,因为其至少可以擦除/编程10000次

辅助存储器

为主存的后援存储器,用来存储当前暂时不需要的程序和数据,不能和CPU直接交换信息

存储器的层次结构

存储器具有三个性能指标:速度,容量,每位价格。一般来说速度越高,位价越高;容量越大,位价越低;容量越大,速度必然越低

由存储器的性能指标之间的关系,可见人们追求的大容量、高速度、低位价的存储器是很难实现的,于是我们提出了存储器的层次结构,来尽可能解决这个矛盾
计算机组成原理——存储器(Memory)_第1张图片
该图中,由上至下,存储器价位越来越低,速度越来越慢,容量越来越大,CPU访问的频度也越来越少

  • 最上层的寄存器通常制作在CPU芯片内部,存储的数据直接在CPU内部参与运算,这里,可能要补充一些知识:寄存器不仅仅存在于CPU内部,I/O端口中也会有寄存器存在。对于有些寄存器,指令对于这些寄存器是可以直接操作的,而且这些寄存器对于机器语言程序员来说并不是透明的,称为体系结构寄存器
  • 中间的主存用来存放将要参与运行的程序和数据,速度与CPU相差较大(而且是剪刀差),为了进行速度匹配,添加了一个高速缓存Cache,现代计算机将Cache也制作在CPU内部
  • 下层的磁盘、磁带属于辅助存储器,容量比内存大得多,用来存放暂时未被使用的程序和数据,CPU不能直接访问辅存,辅存只能和主存交换信息,因此辅存的速度可以比主存慢得多

存储器的存储层次

存储体系:指使用两种或者两种以上的存储介质,用软件、硬件、或者是软硬件相结合的方式将它们链接成一个统一的整体,使得从某一级程序员的角度出发,这个整体(即表明对于程序员来说这个整体是透明的)具有高速度、大容量、低价格的特点

缓存-主存这一层次的速度接近于缓存,而容量和价位却接近于主存
主存-辅存这一层次的速度接近于主存,而容量和价位却接近于辅存
于是可以发现,这样的缓存、主存、辅存三级结构(由两个存储体系构成)解决了前面提到的矛盾,现代计算机系统几乎都具有这两个存储层次

1、缓存-主存

主要解决CPU和主存速度不匹配的问题,于是采用硬件的方法把缓冲主存链接为一个存储体系

解决方式:由于缓存的速度比主存高,于是只要将CPU近期要调用的信息存入缓存(使用了程序的局部性原理),CPU即可直接从速度较快的缓存中获取信息,提高了访存速度。但是同时由于缓存的容量较小,于是需要不断地将主存的数据存入缓存中,使缓存原来的数据被替换掉,这个过程是硬件自动完成的,对程序员来说是透明的

2、主存-辅存

主要解决存储系统容量的问题,于是采用软硬件相结合的方法把主存辅存链接为一个存储体系

解决方式:辅存的容量比主存大得多,当CPU需要辅存中的数据时,再将辅存的信息存入主存,供CPU直接访问,主存和辅存之间的信息调动是由硬件和操作系统共同完成的

虚拟存储系统(Virtual Memory,VM)

虚拟存储器是为了满足用户对存储空间不断增长的需求而提出的一种计算机存储器管理技术,它是建立在主存-辅存这一物理层次结构基础之上,由辅助硬件及操作系统存储管理软件组成的一种存储体系。在这个存储系统中,程序员编写的程序的地址范围与虚拟存储器的地址空间相对应,即程序员编程的时候,可用的地址空间是远远大于主存空间的

  • 虚地址
    • 虚拟存储器的存储单元个数远远大于主存的实际存储单元个数,所以用户编程使用的不是实际地址,而是比实际地址位数更长的地址,这种地址是面向程序需要,而不需要考虑所编程序将来在主存中的实际地址,我们一般称这些虚拟存储器的存储单元对应的地址码为虚地址(虚存地址、虚拟地址、逻辑地址),虚地址从0开始。CPU可以访问的虚地址空间,甚至可以达到整个辅存容量
  • 实地址
    • 我们把主存各个存储单元实际存在的地址称为实地址(物理地址),物理地址才是程序在执行过程中真正能够访问的地址

虚实地址的转化

  • 虚地址转变为实地址的工作是由计算机系统的硬件和操作系统自动完成的,对程序员是透明的。当虚地址的内容就在主存中时,则通过地址变换机制,将虚地址转换为实地址,然后访问主存的实际单元;当虚地址的内容不在主存中时,则要先将虚地址的内容传递到主存中的合适单元后,再让机器使用

对虚拟存储器的直观描述(可能并不那么正确)

  • 当物理内存(就是你的内存条)不够的时候,在硬盘上借用一块空间当内存来用,但是由于这块空间不是物理内存提供的,所以会将这部分硬盘空间称为"虚拟内存"(Windows系统的虚拟内存大小可以进行人为设置,Linux系统中的SWAP(交换分区)也是一个虚拟内存)
  • 由于虚拟内存实际是硬盘中的空间,所以其相同空间的价格要比物理内存低廉,而容量也是以GB为初始单位
  • 执行的程序只会向操作系统申请空间,不会考虑物理内存是否足够大
  • 由于硬盘传输的速度要比内存传输速度慢的多,所以虚拟内存比物理内存的效率要慢得多
  • 断电后数据丢失。和物理内存一样,在电脑遇到突然断电后,虚拟内存中的数据就会丢失,不像我们平时的硬盘(外部存储器)断电还有保存功能

主存储器

主存储器的基本介绍

主存储器内部组成的细化

主存的基本结构在"计算机系统概论"那篇文章中已经进行了粗略的讲解,此处进行细化和补充

实际上,根据MAR中的地址访问某一个存储单元时,存储器内部还需要经过地址译码、驱动等电路的运行,才能找到所需访问的存储单元。将地址线接入译码器,从译码器输出端接出的线称为选择线,用于选定译码器指定的存储单元

实际上,读出数据时,存储器内部还必须经过读出放大器,才能将被选中的存储单元中的存储字送到MDR中;写入时,必须经过写入电路,才能将数据写入被选中的存储单元中

计算机组成原理——存储器(Memory)_第2张图片

主存储器与CPU的联系

  • 物理上的联系
    • 现代计算机的主存都由半导体集成电路构成,驱动器,译码器以及读写电路均制作在存储芯片中,而MAR和MDR则制作在了CPU中(在后续介绍CPU内部结构的时候,就会体现这一点),存储芯片和CPU芯片使用系统总线相连接
  • 功能上的联系
    • 当要从主存储器中读出某一信息字时,首先由CPU将该字的存储地址发送给MAR,通过地址总线,主存接收到地址,CPU发送读命令,主存将该存储单元的信息字读出,放在数据总线上,读操作完成
    • 当要向主存储器存入某一信息字时,首先由CPU将该字的存储地址发送给MAR,通过地址总线,主存接收到地址,CPU发送写命令,主存将数据总线上的信息字写入对应的存储单元中,写操作完成

主存储器中存储单元地址编号的分配方式

不同的机器,存储字长也不同,为了满足字符处理的需要,常用8位二进制表示一个字节,同时存储字长都设定为8的倍数。计算机系统既可以按照字(即存储字长)进行寻址,也可以按照字节进行寻址,即可以使用字地址和字节地址两种地址实现存储器中数据的定位

下面使用大端存储和小端存储两种不同的方式存储同一个十六进制数12345678为例(注意1为最高位,8为最低位)对主存储器存储单元地址的分配方式进行进一步的展示(这里的"大端存储和小端存储"中的"大端"和"小端"即为文章——C语言存储篇中提到的"大端"和"小端"的概念)

  • 大端(大尾)存储方式
    将一个存储单元的高位字节地址作为该存储单元地址的数据存储方式
    计算机组成原理——存储器(Memory)_第3张图片
  • 小端(小尾)存储方式
    将一个存储单元的低位字节地址作为该存储单元地址的数据存储方式
    计算机组成原理——存储器(Memory)_第4张图片

主存的技术指标

存储容量

指主存可以存储的二进制代码的总位数,即存储容量=存储单元个数 * 存储字长,计算出的存储容量的单位为"位"(容量也可以使用字节总数来表示,即存储单元个数*存储字长/8,计算出的存储容量的单位为MB,GB,TB等单位)

对于一个存储芯片而言,容量是以位为单位描述的(比如4K x 8位);对于一个微机系统而言,容量是以字节为单位描述的(比如1MB)

存储速度

存储速度是由存取时间和存取周期来表示的

  • 存取时间
    • 又称为存储器的访问时间,是指从启动一次存储器操作(指读/写)一直到完成该操作所需要花费的全部时间,所以存取时间分为读出时间和写入时间两种
    • 读出时间:从存储器接收有效地址开始,到产生有效输出所需的全部时间
    • 写入时间:从存储器接收到有效地址开始,到数据写入被选中单元为止所需要的全部时间
  • 存取周期
    • 指存储器连续进行两次独立的存储器操作(比如,两次读操作)所需的最小时间间隔(对一个存储单元进行第一次操作开始到完成对第二个存储单元的第二次操作之间的最小间隔),通常来说,存取周期要大于存取时间。存取周期和存储器带宽紧密联系,存储器带宽是以存储器为中心的机器改善机器瓶颈的一个关键因素
    • 存储器带宽
      • 表示单位时间内存储器存取的信息量,单位可以使用字/秒或者字节/秒或者位/秒来表示
      • 提高存储器带宽的措施:1、缩短存储周期 2、增加存储体 3、增加存储字长,使每一个存取周期可以读/写更多的二进制位数

半导体存储芯片

半导体存储芯片采用超大规模集成电路制造工艺,在一个芯片内部集成具有记忆功能的存储矩阵、译码驱动电路和读/写电路等(与存储器相关的MAR和MDR制作在了CPU中)

半导体存储芯片的基本结构

存储矩阵

用于存储0、1代码的一块区域

译码驱动

负责把通过地址总线送来的地址信号翻译成对应存储单元的选择信号,该选择信号在读/写电路的配合下即可实现对被选中存储单元的读/写操作,即存储器的译码驱动

读/写电路

包括放大器和写入电路,用来完成CPU对存储芯片的读/写操作

总线

存储芯片通过地址总线、数据总线和控制总线与外部连接

地址线和数据线的位数共同反映了存储芯片的容量(类比于MAR和MDR的位数共同反映了存储体的容量),比如地址线有10根,数据线有4根,则芯片容量为( 2 10 2^{10} 210)* 4,通常使用1K * 4这样的形式来表示芯片容量(4表示的是数据线个数,即存储字长的位数,1K表示的存储单元总数,每一个地址对应一个字节的空间)

  • 地址总线
    • 为单向输入总线,地址总线的位数与存储芯片的存储单元总数和地址总数有关
  • 数据总线
    • 为双向输入输出总线(有的芯片也会使用成对的数据线分别作为输入和输出),数据总线的位数和存储芯片一次可以读出或者写入的数据位数有关
  • 控制总线
    • 读/写控制线
      • 单向输入总线,用于CPU对存储芯片实现读/写操作
      • 可以使用一根线进行控制: W E ‾ \overline{WE} WE表示低电平尾写操作,高电平为读操作
      • 可以使用两根线分别进行控制: O E ‾ \overline{OE} OE表示进行读操作; W E ‾ \overline{WE} WE表示进行写操作
    • 片选线
      • 用来选择芯片(半导体存储器中具有许多芯片),指出本次访存操作的目标地址针对的是具体是哪个芯片
      • 半导体存储芯片的片选线一般有两种标识方式,一个是 C S ‾ \overline{CS} CS,表示是否选择该芯片,一个是 C E ‾ \overline{CE} CE,表示该芯片是否使能,皆为低电平有效

片选线工作的例子
如果使用 16K x 1位 的存储芯片要组成 64K x 8位 的存储器

由于存储器中的每一个存储单元的容量为8位(一个字节),而存储芯片的存储单元的容量为1位,于是我们要将8个存储芯片看作一组,在进行存储器读/写操作的时候,必须要同时对绑定为一组的这8个存储芯片同时进行读/写操作,此时每一组芯片的容量为 16K X 8位,由于64为16的4倍,所以还需要增加4组这样的 16K x 1位 芯片才能满足要求,形成一个 64K X 8位 的存储器

进行地址编号分配的时候,由于同一组的8个芯片要同时工作,所以每一组共用地址数目为16K的地址编号和一根片选线(8个芯片要么全部被选中,要么全部都不被选中)。比如,当我们需要地址编号为65535(64K-1)对应存储器中的数据时,我们就会将该地址编号对应的那一组的8个存储芯片的片选信号同时置为低电平(8个存储芯片同时处于有效状态),同时其他组的芯片的片选信号全部置为高电平(其他存储芯片同时处于无效状态),从而实现仅仅对此组的8个芯片同时进行存储单元进行访问(在8个芯片相对应的同一位置的那个存储单元处同时读出一位,从而取出地址编号为65535对应存储器中的那8位数据)

译码驱动方式(选中芯片中某一个存储单元)

线选法

数据线有8根,表示每一个存储单元的位数有8位(一个字节);地址线有4根,表示每一个存储单元的总数为16个,所以存储容量表示为16 * 1字节
计算机组成原理——存储器(Memory)_第5张图片

  • 选中存储单元的方式

    • 使用一根字选择线(字线),可以选中一个存储单元的所有二进制位(比如选中了一个字节,8个比特位)
    • 比如,当地址线A3 A2 A1 A0分别为1 1 1 1时,地址译码器输出端的第15根字线有效,这一根线选中的那最后一个存储单元的8位数据就可以直接进行读/写
  • 特点

    • 这种选中存储单元的方式结构简单,但是只适用于容量不大的存储芯片的驱动,如果地址单元数目过多,就会导致译码器输出端上连接的线数将会非常多,线路非常密集
    • 比如有20根地址线,采用线选法,我们需要一个译码器进行译码,这样就需要在译码器的输出端连接1M根线,每一根线对应一个存储单元
    • 本质上来说,线选法是将所有的存储单元排成一列(类似于C语言中一维数组的各个元素空间在内存中的存储方式)
重合法

数据线只有一根,表示每一个存储单元的位数只有一位;地址线有10根,表示每一个存储单元的总数为 1K 个,所以存储容量表示为 1K * 1位
计算机组成原理——存储器(Memory)_第6张图片

  • 选中存储单元的方式

    • 对于图中的矩阵,使用了64根线(X,Y两个方向的译码器输出端各具有32根),与线选法不同的是此时每一个存储单元具有行、列两个地址,通过确定行、列地址,即可实现对该 32X32 矩阵的中每一个存储单元的访问(只有当一个存储单元的行地址和列地址都被选中时,才能对该存储单元进行访问)

    • 比如,当地址线全为 0 的时候(即A9 A8 … A0全部为0),两个译码器输出 X0 和 Y0 有效,对应于矩阵中 0 行 0 列的那个存储单元被选中,只有这个存储单元才能进行数据的输入和输出

  • 特点

    • 实际上,在重合法中,在进行读操作的时候,被选中的行和列中的其他存储单元,自身也会进行数据输出,但是都不会到达I/O读写结构处,只有当一个存储单元的行地址和列地址都被选中时,才能让存储单元中的数据成功到达I/O读写结构处。类似地,进行写操作的时候也是因为是否具有通路的问题,而导致只有那个行地址和列地址同时被选中的那个存储单元,才能实现数据的输入

    • 比如有20根地址线,采用重合法,我们需要两个译码器进行译码,这两个译码器的输入端分别连接10根地址线,则在译码器的输出端一共就可以产生2K根线,每两根相互垂直的线即可选中一个存储单元,这种方式相对于线选法节省了大量的线

    • 本质来说,重合法是将所有的存储单元排成一个矩阵,只有将行地址和列地址进行组合,才是一个存储单元的完整地址

使用重合法进行存储单元选定的例子

如何使用重合法实现一个容量为 1K X 4位 的存储器

一个 1K x 4位 的存储器表示每一个存储单元的位数为4,即我们要把4个基本单元电路(每一个基本单元电路本身可以存储一位比特位的数据)作为一组,同时要实现一根列线控制4个基本单元同时读/写有效,此时1K表示具有1024(210)个存储单元,又每一个存储单元为4位,于是需要26*26个基本单元电路(一个相互垂直的线选中一个基本单元电路)

那么我们可以将这些基本单元电路排布为一个 64 x 64 的矩阵,由于要实现的是一个列选信号同时控制4个基本单元电路,于是我们对应列地址的译码采用4个输入端,16个输出端的译码器,实现每一个输出端控制4列,而行地址依旧使用6个输入端,64个输出端的译码器,这样就可以实现:只要给出一个地址编号,就会同时有4个基本单元电路被选中
计算机组成原理——存储器(Memory)_第7张图片

随机存储器(RAM)

静态RAM(SRAM)

静态RAM基本单元电路
  • 保存一位二进制代码的原理
    • 由于使用的是触发器工作原理存储信息,于是除非电源掉电,否则信息不会自动消失,属于易失性半导体存储器
  • 基本构成
    • 触发器:A为触发器的原端,A’为触发器的非端
    • T1-T4:T1-T4构成了触发器,用于存储二进制数0,1
    • T5-T6:T5-T6为行开关(为每一个存储元独有的,即每一根存储元都具有一个T5、T6),T7-T8为列开关(为一列共用的,即每一列只有一个T7、T8),解决了0,1读/写的问题
    • 三态门:由于存储元为一个双稳态的触发器,于是进行写操作的时候,要将数据分为两个方向,一个方向用来写入数据,一个方向用来写入数据的非,对应与三态门中的两写放

当行地址有效,该行对应的所有存储元的T5、T6都会打开,当列地址有效,该列对应的那个T7-T8就会打开,可以实现读/写操作

计算机组成原理——存储器(Memory)_第8张图片

  • 静态RAM基本电路的读操作
    • 行选信号和列选信号分别使T5、T6导通,T7、T8导通,并且使读选择有效
    • 此时在触发器的A端和数据总线之间构成了一条通路,A端的数据可以沿T6、T8、读放,到达Dout
    • 于此同时,其实T5和T7也是打开的,但是A’端的数据到达写放处就截止了,因为此时并没有写选择有效,所以无通路构成
  • 静态RAM基本电路的写操作
    • 行选信号和列选信号分别使T5、T6导通,T7、T8导通,并且使写选择有效
    • 此时在触发器的A端、A’端和数据总线之间构成了两条通路,Din的数据可以沿三态门的左右两条通路(左Din、反相、T7、T5、A’端 和 右Din、T8、T6、A端)将 数据 以及 数据的非 写入触发器
    • 当写入的二进制数据为1时,就会使得触发器中的T2导通,T1截止;当写入的二进制数据为0时,就会使得触发器中的T2截止,T1导通
    • 当输入信号消失以后,T5、T6、T7、T8截止,T1、T2就保持被写入的状态不变

动态RAM(DRAM)

动态RAM基本单元电路
  • 保存一位二进制代码的原理

    • 具有三管式和单管式两种,共同特点是依靠电容存储电荷的原理来存储信息,即如果电容上存有足够多的电荷,表示存"1",电容上无电荷,表示存"0"
  • 基本构成

    • 三管电路
      • Cg:为电容,解决了0,1存储的问题
      • T1-T3:T1、T2、T3为控制管,解决了0,1读/写的问题。当读选择线有效,T2会打开,当写选择线有效,T3会打开
      • T4:为预充电管,如果预充电信号有效,T4会被打开,VDD会通过T4向读数据线充电,使读数据线变成高电平,将T4打开的操作是进行读操作的时候必须要做的
      • T1:在进行读操作的时候,T1是否打开,决定了是否进行读数据线的放电操作,使读数据线上降为低电平,读出0
    • 单管电路
      • Cg:为电容,解决了0,1存储的问题
      • 字线:即为控制线
      • T:如果相应的行被选中,字线上为高电平,T就会打开

计算机组成原理——存储器(Memory)_第9张图片
计算机组成原理——存储器(Memory)_第10张图片

动态RAM基本电路的读/写操作

  • 三管电路

    • 三管动态RAM基本电路的读操作
      • 预充电信号有效,先使T4打开,VDD会通过T4向读数据线充电,使读数据线变成高电平
      • 读选择线有效,T2打开
        • 如果此时Cg电容具有电荷,即原存二进制代码为1,故电位为1,则T1被打开,此时读数据线就会通过T1和T2进行放电,变成低电平,即读出0
        • 如果此时Cg电容无电荷,即原存二进制代码为0,故电位为0,则T1不会打开,读数据线就会保持高电平,即读出1
      • 所以我们通过读出线的高低电平可以区分是读1还是读0,且结果与原存信息反相,即读数据线降为低电平,读出0信息,原存1;读数据线保持高电平,读出1信息,原存0。所以我们要在读数据线的输出端要加上一个非门
    • 三管动态RAM基本电路的写操作
      • 电路中的电容就可以随输入信息充电,即写1,或者放电,即写0
      • 写选择线有效,T3打开,写数据线通过T3对Cg进行充电或者放电
        • 如果写入1,写数据线为高电平,写数据线就会向Cg进行充电,使Cg中保存下1
        • 如果写入0,写数据线为低电平,写数据线就会向Cg进行放电,使Cg中保存下0
      • 所以我们写入的信息和Cg保存下的信息完全相同
  • 单管电路

    • 单管动态RAM基本电路的读操作
      • 相应的行被选中,字线上的高电平使某电容导通
      • 如果电容上具有电荷,即原存二进制代码为1,则会在数据线上产生电流,读出1,如果电容上无电荷,则在数据线上无电流,读出0
      • 所以读操作结束以后,必然在电容上无电荷,为一种破坏性读出,必须进行再生
    • 单管动态RAM基本电路的写操作
      • 相应的行被选中,字线上的高电平使某电容导通
      • 如果数据线上为高电平,进行电容充电,存入1,如果数据线上为低电平,进行电容放电,存入0
动态RAM的刷新

刷新
电容上的电荷一般只能维持1到2ms,即使电源不掉电,信息也会自动消失,为此,我们必须在这2ms内对所有的存储单元恢复一次原状态,这个恢复过程称为再生或者刷新

刷新的过程实质上为先将原存信息读出,在由刷新放大器形成原信息并重新写入的再生过程,在进行刷新的同时必须停止对存储单元的读/写操作

定时
由于存储单元被访问是随机的,这样就会导致某一些存储单元可能长期得不到访问。如果不进行存储器的读/写操作,这些存储单元内部的原信息会逐渐消失,为此必须使用定时刷新的方法,即在一定时间内,对动态RAM的全部基本单元电路做一次刷新,一般取2ms,这个时间我们称为刷新(再生)周期,刷新是一行一行进行的,而且必须使用专用的刷新电路完成逐行刷新

刷新方式

  • 集中刷新

    • 在规定的一个刷新周期内,对全部存储单元集中一段时间专门用来进行逐行刷新,这段集中的刷新时间称为死时间,或者访存死区
      计算机组成原理——存储器(Memory)_第11张图片
  • 分散刷新

    • 对每行存储单元的刷新操作分散到每一个(新)存储周期中完成,把机器的(新)存储周期分为两个部分,前一个部分用来读/写或者维持信息(这部分时间指的是"如果不进行分散刷新时的原来的存储周期"),后一部分进行刷新(这部分刷新时间为"新存储周期-原来的存储周期",即向存储周期中新添加的一个时间段),死时间消失了,但是存取周期增长了(新存储周期 = 原来的存储周期 + 刷新时间),整个系统的效率降低了,而且存在过度刷新(即刷新次数过多了,没有必要)
      计算机组成原理——存储器(Memory)_第12张图片
  • 异步刷新

    • 为前两种刷新方式的结合,既可以缩短"死时间",又可以充分利用最大刷新间隔2ms
    • 具体操作方法:在2ms内只进行所有行的一次刷新(即使用2ms除以行数即为每一行的刷新间隔),同时,刷新每一行所花费的时间保持为一个存取周期,这样,就不会出现像分散刷新那样过多刷新的情况
    • 例如,对于存取周期为0.5 μs,排列成128 x128的存储芯片,可采取在2 ms内对128行各刷新一遍,即每隔15.6 μs(2 000 μs / 128≈15.6 μs)刷新一行,而每行刷新的时间仍为0.5μs,如图4.26所示。这样,刷新一行只停止一个存取周期,但对每行来说,刷新间隔时间仍为2ms,而“死时间”缩短为0.5μs
    • 这种方式还可以改进:如果再将动态RAM的刷新时间,即"死区"安排在CPU对指令的译码阶段,由于这个阶段CPU不会进行访存,所以这种改进的刷新方式既可以克服分散刷新需要独占一个存取周期用于刷新,使存取周期加长的缺点,又不会出现集中访问那样的死区问题,从根本上提高了整机的工作效率
      计算机组成原理——存储器(Memory)_第13张图片

静态RAM(SRAM)和动态RAM(DRAM)的比较

  • 存储原理
    • DRAM使用电容存储;SRAM使用触发器存储
  • 集成度
    • DRAM的每一个单元电路都非常简单,包含了一个晶体管,一个电容,集成度高SRAM的每一个单元电路包含6个晶体管,集成度低
  • 芯片引脚
    • DRAM的行地址和列地址可以分别进行传送,地址线条数可以减少为原来的一半,自然管脚数减少了;SRAM价格高,速度快,一般使用SRAM都在追求速度,所以SRAM使用时就不会采用行地址和列地址可以分别进行传送的方式,于是管脚数自然就会比较多
  • 功耗
    • DRAM功耗小,只需要对电容进行充放电,进行刷新;SRAM中的由T1-T4构成的双稳态触发器,工作以后有三个管子一直保持在导通状态,功耗高
  • 价格
    • DRAM的结构简单,价格低;SRAM的结构复杂,价格高
  • 速度
    • DRAM由于要对电容进行充放电,速度较慢SRAM使用触发器存放信息,速度较快
  • 刷新
    • DRAM需要进行刷新;SRAM不需要进行刷新

所以通常情况下,把DRAM作为主存,SRAM作为Cache

只读存储器

按照ROM的原始定义,一旦写入原始信息,就不能发生改变,但是随着用于需要的变化,总希望能够修改ROM内部的原始信息,这就出现了PROM、EPROM、EEPROM等,对于ROM来说,基本器件分为MOS型和TTL型

掩模ROM

这里仅仅介绍MOS型掩模ROM

  • 基本介绍
    • 只能进行读操作的只读存储器,为最开始的,符合ROM的原始定义的只读存储器
    • 掩模ROM是由生产厂家采用掩模工艺,在生产过程中将固定的程序代码直接注入ROM芯片中,用户不能修改其内容。掩模ROM大量生产时,成本很低。掩模ROM只能用于特定场合,给用户带来了很大的限制,灵活性低
  • 读操作
    • 在进行读操作的时候,使用重合法驱动,行选择线和列选择线交叉处可以有耦合元件MOS管,也可以没有。当一个交叉处被列选择线和行选择线同时选中,如果该交叉处具有耦合元件MOS管,会因为导通而使列线输出为低电平,经过读放大器反相,读出的结果为1,如果该交叉处无耦合元件MOS管,列线直接输出1,经过读放大器反相,读出的结果为0,所以,在行列交叉处是否具有耦合元件MOS管,就可以区分原存1还是0
  • 不可变的原因
    • 由于此类ROM制成以后不可能改变原行列交叉处是否具有耦合元件MOS管,所以用户是无法改变原始状态的

计算机组成原理——存储器(Memory)_第14张图片

PROM

  • 基本介绍
    • 为可以实现一次性编程的只读存储器
    • 买回来的PROM为空片,即所有单元存储的二进制数据皆为全1,用户需使用专用的编程器写入代码,写入一个PROM只需要几分钟,操作方便。但是PROM的一次编程性不适合于在研制产品过程中使用
  • 编程操作
    • 基极由行线控制,在发射级与列线直接具有一个镍铬合金薄膜制成的熔丝(可以使用光刻技术实现),集电极接Vcc,熔丝断和未断可以区别其存储的信息为1还是0
    • 用户使用前可以按照自身需求,将信息存入行列交叉的耦合元件中,如果要存储0,则给耦合元件一个大电流,把熔丝烧掉,如果要存储1,则不动,保持熔丝不断
  • 读操作
    • 在进行读操作的时候,当交叉处被选中时,如果该处耦合元件的熔丝断开,读出0,如果没断开,读出1
  • 编程只能一次性的原因
    • 已断的熔丝是无法再恢复的,于是只能实现一次性编程,编程以后,不得再修改

计算机组成原理——存储器(Memory)_第15张图片

EPROM以及EEPROM

  • 基本介绍
    • EPROM为一种可擦除可编程只读存储器,可以允许用户使用专用的编程写器对存储信息进行任意次改写,存储在EPROM中的内容可以长期保存达几十年之久。目前使用的比较多的EPROM是由浮动栅雪崩注入型MOS管构成的,又称为FAMOS型EPROM
    • 这类芯片的外引脚除了地址线、数据线以外,还有两个电源引出头Vcc和Vpp,其中Vcc接+5V,Vpp平时接+5V,当其接+25V时用来完成编程操作。Vss为地。CS(反)为片选端,读出时为低电平,编程写入时为高电平。PD(反)/propr为功率下降/编程输入端,在读出时为低电平,当此端为高电平时,可以使EPROM功耗由525mW降至132mW,当需要进行编程时,此端需增加宽度为50-55ms、+5V的脉冲
  • 编程操作
    • 在漏端D加上正电压(比如25V、50ms宽的正脉冲),就会形成一个浮动栅,它的存在会阻止源S与漏D之间的导通,使该MOS管处于0状态;如果对D端不加正电压,就不能形成浮动栅,此MOS管就可以正常导通,呈1状态。所以,用户可以按照自身需要对于不同位置的MOS管D端施加正电压或者不动,来制成所需的ROM
  • 擦除操作
    • 紫外线照射法
      • 用户如果需要重置,可以使用紫外线照射芯片上的窗口,来驱散全部的浮动栅,但是擦除时间比较长(大约15分钟),由于每一次紫外光照射时是通过石英窗口对整个芯片进行照射的,所以不能对个别需要改写的单元进行单独擦除或重写,这是EPROM的不足之处
    • 电气方法
      • 使用电气方法将存储内容进行擦除,再重写
    • 字擦除/页擦除
      • 可以字节为单位进行内容改写,而且无论是字节,还是正片改写,均可在应用系统中在线进行。这种EPROM就是EEPROM(电可擦除可编程只读存储器)

计算机组成原理——存储器(Memory)_第16张图片

存储器与CPU的连接

扩展存储容量时的局部连接

单片存储芯片的存储容量是有限的,一般不能满足实际需求,因此,必须将若干个存储芯片相连才能组成足够容量的存储器,这种操作称为存储容量的扩展,通常有位扩展和字扩展两种方式

位扩展

扩展存储字长
进行位扩展的时候,芯片的对应地址线是连接在同一条线上的,即存储数据的时候是在芯片的对应存储单元处进行存储,而数据线不是连接在同一条线上的,即对应的存储单元中存储的数据是不一样的 C S ‾ \overline{CS} CS W E ‾ \overline{WE} WE 都分别连接在一起,即进行读/写操作的时候,是同时进行读/写操作的;进行片选的时候,是同时被/不被选中的

比如2片 1K X 4位 的芯片可以组成 1K X 8位 的存储器:将两片芯片的地址线 A9 - A0、 C S ‾ \overline{CS} CS W E ‾ \overline{WE} WE 都分别连接在一起(必须这样,因为要实现同时访问两个芯片的存储单元),其中一片的数据线作为4位 D7 - D4,另一片的数据线作为低4位 D3 - D0,这样就可以构成一个 1K X 8位 的存储器
计算机组成原理——存储器(Memory)_第17张图片

字扩展

增加存储器字的数量(即存储单元的个数,或者说是存储单元地址编号的总数)
进行字扩展的时候,芯片的 C S ‾ \overline{CS} CS 是有进行区分的,即一个被选中,另一个就不会被选中,所以即使对应的地址线、数据线、 W E ‾ \overline{WE} WE分别都是连接在同一条线上的,这两个芯片之间也是毫不相干的,因为两个芯片不可能同时进行读/写操作,存储的数据必定是不一样的

比如使用2片 1K X 8位 的存储芯片可以组成一个 2K X 8位 的存储器,即存储字的数目增加了一倍:将 A10 作为片选线,由于存储芯片的片选输入端要求低电平有效,于是当 A10 为低电平时, C S 0 ‾ \overline{CS0} CS0 有效,于是选中的是左边的芯片,当 A10 为高电平时,反相以后 C S 1 ‾ \overline{CS1} CS1 有效,于是选中的是右边的芯片

计算机组成原理——存储器(Memory)_第18张图片

字、位扩展

既增加存储字的数量,又增加存储字长(画图过程中先画扩位操作,再画扩字操作)

比如使用8片 1K x 4位 的芯片组成 4K x 8位 的存储器:从左到右,每相邻两个芯片的 C S ‾ \overline{CS} CS W E ‾ \overline{WE} WE 都是连接在同一根线上的,同时两个芯片的数据线并不是连接在一起的,所以每相邻两个芯片都是一组 1K x 8位 的存储结构

如果将它们看成一个整体,组与组之间的片选线并不是连接在一起的,即使即使对应的地址线、数据线、 W E ‾ \overline{WE} WE 分别都是连接在同一条线上的,这两个组之间也是毫不相干的,显然,这种连接方式实现了字扩展,由于一共具有4组,于是就扩展了4倍

最后得到了一个 4K x 8位 的存储器

计算机组成原理——存储器(Memory)_第19张图片

存储器与CPU的整体连接

芯片地址线的连接

当存储芯片的容量不同时,其地址线数也不同,CPU的地址线数往往比存储芯片的地址线数要多,此时我们通常将CPU的地址线的低位和存储芯片的地址线相连接(用于选择芯片内部的各个存储单元),地址线的高位在存储芯片扩展的时候用到 或者 作为片选线等

比如假设CPU的地址线为16位 A15-A0,而1K X 4位 的存储芯片仅仅只有10根地址线 A9-A0,此时,我们一般会选择将CPU的低位地址线 A9-A0 与存储芯片的地址线 A9-A0 进行连接

芯片数据线的连接

当然,CPU的数据线和存储芯片的数据线数量也不一定会相等(通常CPU的数据线数会大于存储芯片的数据线数),此时必须对存储器进行位扩展,使CPU的数据线数和存储器的数据线数相同

芯片控制线的连接(主要是片选线)
  • 读/写命令线的连接

    • CPU的读/写命令线一般可以直接与存储芯片的读/写控制端相连,通常高电平为读,低电平为写,有些CPU的读/写命令线的分开的,此时CPU的读命令线应该与存储芯片的允许读控制端相连,而写命令线应该与存储芯片的允许写控制端相连接
  • 片选线的连接

    • 存储器内部具有许多存储芯片,存储芯片的片选控制端是否能接收到CPU发送的片选有效信号就决定了这一片存储芯片当前是否被选中进行读/写操作
    • CPU的访存控制信号 M R E Q ‾ \overline{MREQ} MREQ
      • 片选有效信号与CPU的访存控制信号 M R E Q ‾ \overline{MREQ} MREQ有关,因为只有CPU要进行访存的时候,才需要对存储芯片进行片选,所以CPU的访存控制信号引脚必须要参与片选线的连接,从而保证是在CPU访存控制信号有效时,才会对存储芯片进行片选。防止把地址总线上对I/O设备的地址信号错误地认为是对存储芯片内部存储单元的地址信号,将CPU的控制线加入片选线的连接以后,可以保证芯片在确实需要该芯片工作的时刻才会被选中
    • CPU的地址线
      • 片选有效信号还与CPU的地址线有关,因为一般来说CPU的地址线数目是要多于存储芯片的地址线数的,所以CPU的高位地址线可能就会和访存控制信号 M R E Q ‾ \overline{MREQ} MREQ共同产生存储芯片的片选信号,即存储芯片的片选信号也是根据CPU想要访问的地址的不同,从而实现对存储芯片的正确选择
      • 一般使用CPU低位的地址线与存储芯片的地址线相连接其实表示的是一般使用CPU高位的地址线进行片选信号的构造,即利用CPU要访问的地址二进制数的高位二进制数进行不同存储范围(即不同存储芯片)的选取
    • 一些逻辑电路
      • 通常还需要借助一些逻辑电路,比如译码器和其他各种门电路,来产生片选有效信号
    • 片选信号的产生方法
      • 全地址译码方式
        • 除直接与存储器芯片相连的地址线外,所有剩余的高位地址线都被连接到地址译码器,参加地址译码,其译码输出就作为存储器芯片的片选信号。存储器芯片中的每一个存储单元只对应内存空间的一个地址,节约了内存空间。但是由于所有的高位地址线都要参与译码,所以导致译码电路复杂,成本上升
      • 部分地址译码方式
        • 某些高位地址线被省略而不参加地址译码,简化了地址译码电路,但地址空间有重叠,浪费了一定的内存空间,但是译码电路简单
        • 重叠空间数满足下述关系:重叠空间数= 2n(其中,n为不参加地址译码的高位地址线数)
        • 在重叠空间中,只允许连接一块芯片,以确保内存单元使用的唯一性,否则会使存储器操作发生混乱。这种译码方式在小型的微型机应用系统中得到了广泛的应用
      • 线选法
        • 线选法是指用存储器芯片片内寻址以外的系统的高位地址线中的每条地址线直接作为一个存储器芯片的片选控制信号,不进行译码操作。采用线选法时,把作为片选信号的那一根地址线连至各芯片(或芯片组)的片选端 C E ‾ \overline{CE} CE (或 C S ‾ \overline{CS} CS),当某个芯片的 C E ‾ \overline{CE} CE为低电平时,则该芯片被选中。需要注意的是,用于片选的地址线每次寻址时只能有一位有效,不允许同时有多位有效,这样才能保证每次只选中一个芯片或一个芯片组(进行了字扩展)。线选法的优点是选择芯片不需要外加逻辑电路,译码线路及其简单;缺点是把地址空间分成了相互隔离的区域,且地址重叠区域多,不能充分利用系统的存储器空间。因此,这种方法适用于扩展容量较小的系统
存储芯片型号以及数量的确定

合理选择存储芯片主要是指存储芯片类型(RAM或者ROM)和芯片数量的选择
芯片类型:通常使用ROM存放系统程序、标准子程序和各类常数;而RAM是为用户编程而设置的
芯片数量:要尽量使连线简单方便

存储器与CPU的整体连接的例题

计算机组成原理——存储器(Memory)_第20张图片
计算机组成原理——存储器(Memory)_第21张图片
芯片类型和数目的选择
根据地址编号数目(系统程序区需要800H个地址编号,即211个地址编号;用户程序区需要400H个地址编号,即210个地址编号),即可得出ROM和RAM芯片的容量(ROM对应系统程序区,所以需要211个存储单元;RAM对应用户程序区,所以需要210个存储单元)

再考虑到题目所给芯片类型和CPU的数据线数目

所以我们选择 2 个 1K x 4位的 RAM 芯片(要进行位拓展)和 1 个 2K x 8位的 ROM 芯片

芯片与CPU的连线
先将题目要求的十六进制地址编号范围转化为二进制地址编号范围(注意书写的时候,CPU具有多少根地址线,我们也要对应写出多少二进制位,这是为了方便进行片选信号的构造)

计算机组成原理——存储器(Memory)_第22张图片

  • 芯片地址线的连接
    由于ROM存储器容量为 2K X 8位,于是ROM的地址线具有11根,于是我们将CPU的低11位地址 A10-A0 与ROM地址线相连;由于RAM存储器容量为 1K X 8位,于是RAM的地址线具有10根,于是我们将CPU的低10位地址 A10-A0 与RAM地址线相连,CPU剩下的高位地址线与访存控制信号 M R E Q ‾ \overline{MREQ} MREQ共同产生片选信号

  • 芯片数据线的连接
    将ROM的4根数据线与CPU的4根数据线直接相连,两个RAM的2根数据线分别与CPU的4根数据线直接相连

  • 芯片控制线的连接

    • 读/写命令线的连接

      • 两个RAM存储器的读写线都和CPU的读写控制线连在一起
    • 片选线的连接

      • 对上面列出的二进制地址范围进行观察可以发现,在芯片的地址编号范围中CPU的A12和A15始终为低电平,A13和A14始终为高电平,A11在用户程序区地址范围(RAM)内为高电平,在系统程序区地址范围(ROM)内为低电平,A10在用户程序区地址范围(RAM)内为低电平
      • 由于CPU的访存控制信号 M R E Q ‾ \overline{MREQ} MREQ和译码器的一个控制端 G 2 B ‾ \overline{G2B} G2B都是低电平有效,于是我们将二者相连,由于CPU的A15始终为低电平,A14始终为高电平,于是我们再将A14,A15分别与译码器控制端的G1和 G 2 A ‾ \overline{G2A} G2A相连,保证译码器的正常工作
      • 由于CPU的A13始终为高电平,A12始终为低电平,A11在用户程序区地址范围内为高电平,在系统程序区地址范围内为低电平,于是我们将A11与输入端A连接,将A13和A12与输入端C、B连接,根据译码器的工作原理,可知,当CPU地址线输出的地址为用户程序区地址范围内的地址时, Y 5 ‾ \overline{Y5} Y5会输出低电平,当CPU地址线输出的地址为系统程序区地址范围内的地址时, Y 4 ‾ \overline{Y4} Y4会输出低电平,这样就把访问两个存储器的信号进行了区分,可以将ROM的片选端和 Y 4 ‾ \overline{Y4} Y4相连,形成了一个对于ROM芯片的片选信号
      • 由于A10在用户程序区地址范围内为一直为低电平,于是最后再把 Y 5 ‾ \overline{Y5} Y5与A10进行一个与非操作(注意芯片的片选段是低电平输入有效),把两个RAM的片选端与 Y 5 ‾ \overline{Y5} Y5与A10进行一个与非操作(注意是低电平输入有效)的结果连接在一起,形成了一个对于两个RAM芯片的片选信号

计算机组成原理——存储器(Memory)_第23张图片

提高访存速度的措施

由于"存储墙"成为提高系统性能的主要障碍,于是必须要使用一些手段来提高访存速度,可以通过调整主存的结构、采用高性能的存储芯片、采用层次结构("层次结构"这种方法前面已经介绍过了,前两种方法在此次开始讲解)等方法实现

主存的结构

单体多字结构
  • 原理
    • 由于程序和数据在存储体中一般都是连续存放的,CPU取出信息也是连续从存储体中取出的,于是就可以构造这么一种存储结构,在一个存取周期内,从同一个地址取出连续的4条指令,先将这些指令放入数据寄存器中,然后逐条将指令送到CPU进行执行(实际上就是把存储器的存储字长进行拓展,大于CPU字长,这里举的例子是 4*CPU字长 = 存储器的存储字长,同时数据总线的宽度等于CPU字长),相当于每隔1/4周期向CPU发送一条指令,这样就增大了存储器的带宽,提高了单体存储器的工作速率
      计算机组成原理——存储器(Memory)_第24张图片
  • 缺陷
    • 显然,采用这种方法的前提是指令和数据在主存中都是连续存放的,如果在读取过程中遇到转移指令或者操作数不是连续存储的情况,这种方法的提速效果就不明显了
    • 在CPU向存储器中写一个长度为一个CPU字长的数据,要将数据先写入到单字长寄存器中,再写入到四个CPU字长的数据寄存器中,最后写入存储器中,这就有一个问题,如果仅仅是图中这么简单的结构,就会造成原来只需要写入一个CPU字长的数据,但是实际写入了四个CPU字长的数据,会产生一些问题,如果要实现一个CPU字长的数据的正确写入,那我们必须要进行存储器结构的复杂化
多体并行系统
  • 基本介绍

    • 多体并行系统就是采用多体模块组成的存储器,每一个模块具有相同的存储容量和存取速度,各个模块都具有各自的地址寄存器(MAR)、数据寄存器(MDR)、地址译码、驱动电路和读/写电路。它们相互独立,互不影响,既可以并行工作,也可以交叉工作
  • 顺序存储(高位地址交叉编址)

    • 原理
      • 程序和数据按照体中的地址顺序存放,即一个体存满了,才接着往下一个体进行存储,即一个体中的地址是连续的,这有利于存储器的扩充,显然,这种编址方式对于一个CPU给定的地址来说,这个地址的低位是用来进行体中地址的选择的,这个地址的高位是用来进行各个体的选择的,即高位表示体号信息,低位表示体内地址信息(简单来说就是,低位数值变动,效果是在不同的体内地址信息之间跳跃;高位地址变动,效果是在不同的体号信息之间跳跃)
        计算机组成原理——存储器(Memory)_第25张图片
    • 效果
      • 这种编址方式,只要进行合理的调动,就可以使不同的请求源在同一个时间段内对不同的体进行访问,实现并行工作,比如在CPU和一个体进行信息交换的时候,另一个体可以和I/O设备进行信息交换,两个体并行工作,互不干扰
  • 交叉存储(低位地址交叉编址)

    • 原理
      • 程序和数据连续存放在相邻的体中,显然,这种编址方式对于一个CPU给定的地址来说,这个地址的低位是用来进行各个体的选择的,这个地址的高位是用来进行体中地址的选择的,即高位表示体内地址信息,低位表示体号信息(简单来说就是,高位数值变动,效果是在不同的体内地址信息之间跳跃;低位地址变动,效果是在不同的体号信息之间跳跃)
        计算机组成原理——存储器(Memory)_第26张图片
      • 这种编址方式又称为模M编址(M为模块数),表示的含义是每一个地址先转化为十进制数,然后根据模M计算的结果先挑选对应的体,再进行地址对应存储单元数据的读/写操作,一般我们会把M取为2的方幂,使电路比较简单(有的机器为了减少存储器冲突,将M取为质数)
    • 效果
      • 采用交叉编址的方法,虽然每一个存储器的存取周期并未得到缩短,但是由于CPU可以交叉对每一个体进行访问,使得各个存储器的读/写过程相互重叠进行,最终在一个存储周期内实现了多个存储字的提供(除了第一个周期以外),增加了存储器的带宽
    • 案例
      计算机组成原理——存储器(Memory)_第27张图片
      对于第一个体,假设所有体的存取周期皆为T,即在访问每一个体的时候,存储器都需要消耗T的时间,才能把数据取出,于是就有了第一层的那个T时间(注意,在第一个体内部正在取出数据的同时,第二个体也被CPU访问了,对应于第二层),第一个体在经历了时间T以后,最终取出了数据,接着由于数据总线的传输周期为 τ \tau τ,于是此时数据总线要消耗 τ \tau τ的时间进行数据传输(而且由于每一个体的存储字长和数据总线的宽度一致,所以要等到传输完毕以后,才能传输下一个存储字长的数据),在传输完毕以后,由于第二个体的存储周期也到了,即第二个体取出数据了,于是数据总线此时刚刚传输完毕第一个存储字长的数据,立即开始了第二个存储字长的数据的传输,以此类推,我们可以发现,除了最开始经历的T时间内没有数据的传输以外,后面由于体与体之间的读/写过程都是相互重叠进行的,就会导致上一个体的数据传输完毕时,这个体的数据就已经取出了,所以都是经过一个数据传输周期以后,立马又进行数据传输(即后面整个过程,数据总线就没停下来过,一直都在传输数据)
      其实上面这段描述中具有一个点我没有讲清楚,即为什么在第一个体的访问结束,将其数据传送完毕以后,第二个体的数据也已经被取出了呢?这是因为访问体的时候,CPU需要对体进行启动操作,这个时候,控制总线是有控制信号进行传送的,当第一个控制信号到达启动第一个体后(中间经过了 τ \tau τ的时间),才能进行第二个体的启动,即第一个体和第二个体的启动时间恰好相差了 τ \tau τ的时间,即图中每一层靠左边的每一级台阶的宽度即为 τ \tau τ,这就导致了每一层靠右边的的每一级台阶的宽度也为 τ \tau τ,所以数据总线进行一次数据传送后,立刻就会有下一个体的数据待传送
      根据此图可知,CPU每经过一个 τ \tau τ时间,就会启动对下一个体的数据访问,所以必须要满足公式T <= n * τ \tau τ,因为n * τ \tau τ表示的是访问了n个体所需要的时间长度(即全部的体都访问过一遍),访问了所有n个体以后CPU就会重新访问最最开始访问的那个体,这个时候,只有这个体已经经过了存取周期了(可以直接进行新一次的读/写操作,不需要CPU进行等待)才能永久保持前面说的那个体与体之间的读/写过程相互重叠进行的状态不动
      通过该图,我们可以轻易地得出一个公式:连续读取n个存储字长的数据所需时间为T +(n - 1) τ \tau τ
  • 存储控制部件的基本结构

    • 基本介绍
      • 多体模块存储器不仅要与CPU交换信息,还要与辅存、I/O设备,乃至I/O处理机交换信息。因此,在某一时刻,决定主存究竟与哪个部件交换信息必须由存储器控制部件(简称存控)来承担。存控具有合理安排各部件请求访问的顺序以及控制主存读/写操作的功能
    • 排队器
      • 由于要求访存的请求源很多,而且访问都是随机的,为了避免防止两个请求源同时访问同一个存储体,避免将代码错送到另一个请求源上,存控中必须有一个排队器,用来确定请求源的优先级
      • 优先级原则
        • 对于易发生代码丢失的请求源,列为最高优先级,比如外设的信息最容易丢失,于是优先级最高
        • 对于严重影响CPU工作的请求源,给予次高的优先级,否则会导致CPU工作失常,比如写数请求高于读数请求,读数请求高于读指令请求,因为如果运算部件的计算结果不能尽快被送走,将会严重影响后续指令的执行,而且如果没有取出操作数参与运算,即使取出了再多的指令都无济于事
    • 存控标记触发器Cm
      • 用来接收排队器的输出信号,一旦响应了某一个请求源的请求,Cm就会被置为1,会启动节拍发生器进行工作
    • 节拍发生器
      • 用来产生固定节拍,与机器主脉冲同步,使得控制线路按照一定的时序发出信号
    • 控制线路
      • 将排队器给出的信号和节拍发生器提供的节拍信号配合,向存储器的各个部件发送各种控制信号,实现对总线的控制以及完成存储器的读/写操作,并向请求源发送响应信号,表示存储器已经响应了请求

存储器的校验(使用汉明码进行纠错)

在计算机运行过程中,由于种种原因致使数据在存储过程中可能出现差错。为了能及时发现错误并及时纠正错误,通常可将原数据配成汉明编码

基本介绍

纠错理论

公式:L - 1 = D + C (D >= C)

  • L表示编码最小距离(最小编码距离指的是在一种编码系统中,任意两组合法代码之间的最小二进制位数的差异,简单来说就是合法代码的位数最小差几位);D表示检测错误的位数(即检错能力);C表示纠正错误的位数(即纠错能力)
  • 根据纠错理论可知,任何一种编码是否具有检测能力和纠错能力,都与编码的最小距离有关,编码最小距离L越大,则其检测错误的位数D越大,纠正错误的位数C也越大,且纠错能力恒小于或等于检错能力。可见,倘若能在信息编码中增加若干位检测位,从而增大L,显然便能提高检错和纠错能力。汉明码就是根据这一理论提出的具有一位纠错能力的编码
汉明码
  • 为了及时检测到数据在存储过程中发生的差错,通常可以在原始数据上添加检测位,形成汉明码

    • 设欲检测的二进制代码为n位,为了使其具有纠错能力,需要增添上k位检测位,组成 n + k 位的新代码,而且,为了能够准确地对错误二进制位进行定位以及指出代码没有发生错误,规定新增添的检测位数k要满足2k >= n + k + 1,通过该公式就可以确定给定代码需要添加的(最小)检测位数(后续会定性地证明该公式的合理性)
      计算机组成原理——存储器(Memory)_第28张图片
  • 汉明码是根据纠错理论提出的具有一位纠错能力的编码方式,采用奇偶校验和分组校验的方式

汉明码的构造
  • k位的检测位在新代码中位置的确定

    • k位检测位检测位放置于添加入检测位以后的新代码的第1、2、4、8…2^(k-1)位上,这些检测位这么插入是为了确保它们能够分别完成新代码中由不同的数位所组成的小组(下面会提到怎么进行小组分配)的奇偶检测任务(奇偶检测任务指的是使检测位和它所在的小组中1的个数为奇数或者为偶数,奇数还是偶数根据实际情况进行选择)
  • 每一个检测位的小组构成

    • 小组划分所需要遵守的规则
      • 1、每一个小组中具有而且只有一个检测位存在
      • 2、每两个小组共同具有这两个小组各自检测位的位序之和的那一位,其他小组没有这一位(比如一个小组的检测位在新代码中为第 i 位,另一个小组的检测位在新代码中为第 j 位,则这两个小组独占了新代码中的第( i + j )位,其他小组是没有新代码中的这个第( i + j )位的),下面的第3点规则类似
      • 3、每三个小组共同具有这三个小组各自检测位的位序之和的那一位,其他小组没有这一位…以此类推,可以唯一确定每一个小组中所包含新代码中的各个位
    • 确定小组成员的方法就是在写每一组的时候,都要先计算不在该组中的位,在进行书写,不要想着一下子把全部的组的成员都看出来,一组一组慢慢写,自然简单
      在这里插入图片描述
  • 检测位上数值的确定(1还是0)

    • 先确定使用的是配偶原则还是配奇原则,然后对应设置检测位的数值,使得每一组中的1的数量相应变成偶数或者是奇数即可

汉明码的纠错

  • 使用汉明码进行纠错假定了一个前提:整个代码只有一位出错了(计算机中一位出错的概率最大,可以占到所有出错类型概率的90%)
  • 汉明码的纠错过程实际为对存储以后的汉明码按照配偶原则或者配奇原则(即原来构造汉明码的时候使用的原则)重新计算每一组中的1的个数是否符合原来指定的标准(可以使用异或运算的特性进行检测)
    • 如果符合,则说明代码完全没有出错,不需要进行纠错
    • 如果不符合,则说明代码出错了,需要进行纠错。此时可以将各个组中的成员进行异或运算,并将计算结果按序进行排列(从低位到高位依次为第一组的异或计算结果、第二组的异或计算结果…第k组的异或计算结果),从而可以精确得出出错的那一位所在汉明码中的位序
  • 汉明码纠错的原理(以配偶原则为例进行讲解)
    • 各个组的异或计算结果,按序依次进行排列,对于每一个组来说,如果这一组的异或计算结果为1,则表示出错位必定存在于这一组中(注意,代码中的一位出错了,可能会导致多个组的计算结果都会出错,因为存在多个组共同拥有代码中的同一位的情况),现在进行分类讨论:
      • 如果结果显示只有一组的计算结果出错(即我们按序写出异或计算结果后,只有一个组对应得出的运算结果为1,其他均为0)。假设是第k组的异或计算结果出错了,则我们可以知晓:既然只有一组的结果出错,则必然出错的这一位是这个组独有的,按照分组的规则可以知道,出错位在整个代码中的位序为第2(k-1),而这恰恰就是按序写出异或计算结果后,整个运算结果构成的二进制序列对应的十进制数
      • 如果我们假设有两组的计算结果同时出错,则必然出错位为只有这两个组才共同具有的那一位,假设两个组分别为第 i 组和第 j 组,则按照分组规则,只有这两个组才共同拥有的是第2(i-1)+2(j-1),而这也正是按序写出异或计算结果后,整个运算结果构成的二进制序列对应的十进制数
    • 简单来说,汉明码的分组思路就为后面进行纠错提供了一个极其简单的方法,即按序写出各个组的异或计算结果后(从低位到高位依次为第一组的异或计算结果、第二组的异或计算结果…第k组的异或计算结果),整个运算结果构成的二进制序列对应的十进制数即为出错位在整个代码中的位序
  • 其实根据这个纠错方式,我们也可以对新增添的检测位数k要满足2k >= n + k + 1这个公式的合理性进行验证:
    • 由于最后我们要通过那k位二进制数区分出情况大致可以分为两大种:
      • 1、出现了错误,这个错误的出现位置有n+k种情况(因为汉明码具有n+k个二进制位,每一位都可能出错)
      • 2、没有出现错误
    • 细分过后,会发现我们需要通过一个k位二进制数(即检测时,将k组的运算结果按序排列组成的那个k位二进制数)区分出n+k+1种情况,而对于一个k位的二进制数来说只有2k >= n + k + 1这个公式满足之后(一个k位的二进制数最多可以表示2k不同数,我们可以将每一个数值对应表示一种情况的发生),才能够有能力区分出这n+k+1种情况,所以要实现能够准确地对错误二进制位进行定位以及指出代码没有发生错误,则必要条件为"满足公式2k >= n + k + 1"

汉明码案例(构造+纠错)

  • 构造汉明码
    • 想要存储的原代码为b4 b3 b2 b1(0101),可知n = 4,根据公式2k >= n + k + 1,可知k最小值为3,而且将各个检测位插入,形成的新代码为C1 C2 b4 C4 b3 b2 b1,由于一共有三个检测位,于是一共有三组,且按照分组规则,每一个小组及其成员分别为C1 b4 b3 b1,C2 b4 b2 b1,C4 b3 b2 b1,现在假设按照配偶原则进行配置,于是可以知道,C1 = 0,C2 = 1,C4 = 0,于是新代码为0100101
  • 汉明码纠错
    • 假设出错以后的汉明码为0100111,如果我们要检查是否出错了,可以计算每一组中的成员异或结果:第一组:0 异或 0 异或 1 异或 1,结果为0,没有问题;第二组:1 异或 0 异或 1 异或 1,结果为1,出问题了;第三组:0 异或 1 异或 1 异或 1,结果为1,出问题了,现在我们知道汉明码已经出错了,于是我们接着要对出错的那一位进行定位,方法为将每一组的成员异或结果进行按序排列,结果即为出错位的位序,排列以后为110,对应十进制数6,于是出错的位为第六位,所以正确的汉明码为0100101

高性能存储芯片

为了进一步提供存储芯片DRAM的性能,开发出了基于DRAM结构的增强功能,出现了高性能存储芯片,比如SDRAM、RDRAM、CDRAM

SDRAM

与常用的异步RAM不同,SDRAM与处理器的数据交换同步于系统的时钟信号,并且以处理器-存储器总线的最高速度运行,CPU不需要插入等待状态(在典型的DRAM中,处理器将地址和控制信号送入存储器以后,都要经过一段延时,供DRAM执行各种内部操作,而由于为异步DRAM,而且CPU的速度一般都是高于RAM的,于是此时CPU只能等待,不能利用这个时间去处理其他请求),而SDRAM为同步DRAM,即SDRAM会在系统时钟的控制下进行数据的读出与写入,CPU给出的地址信号一般都会被SDRAM锁存,直到指定的时钟周期数后在进行响应,此时CPU就可以去执行其他任务而无需等待了

比如系统时钟周期为10ns,存储器接收到地址以后需要50ns的时间才能读出数据。如果使用的是异步DRAM,CPU要等待50ns来获取数据;而如果使用的同步DRAM(即SDRAM),CPU只需要将地址放入所存器中,在存储器进行读操作的期间可以去完成其他操作,到了CPU计时到5个时钟周期以后,即可获得从存储器读出的数据。简单来说就是,SDRAM由于与处理器的数据交换同步于系统的时钟信号,于是处理器就可以知道何时SDRAM会将需要读取的数据取出,只要到点去拿就可以了,不需要一直傻等着存储器,期间可以去做其他事情,而异步DRAM下,由于存储器不知道何时存储器会读出数据,于是必须要一直进行等待,直到存储器取出数据为止

RDRAM

Rambus开发的RDRAM采用专门的DRAM和高性能的芯片接口取代了原有的存储器接口,主要解决了存储器带宽的问题,可以通过高速总线获得存储器请求,不像传统的DRAM采用 W E ‾ \overline{WE} WE C A S ‾ \overline{CAS} CAS R A S ‾ \overline{RAS} RAS信号来控制,而是采用异步的面向块的传输协议传送地址信息和数据信息。一个RDRAM芯片就像一个存储系统,通过一种互连电路RamLink,将各个RDRAM芯片连接成一个环,数据通信在主存控制器的控制下进行,数据交换以包为单位进行

CDRAM

CDRAM即带有Cache的DRAM,是在DRAM芯片中又集成了一个小的SRAM(Cache一般就是由SRAM构成的),也称为EDRAM(增强型的DRAM)

计算机组成原理——存储器(Memory)_第29张图片
图中1M x 4位 的CDRAM 芯片中具有排列成2048 x 512 x 4位 的DRAM阵列512 x 4位 的SRAM Cache,可以看到整个CDRAM芯片的对外地址线仅仅只有11根,而 1M x 4位 的CDRAM如果按照之前的常规设计思路需要20根地址线才能满足1M存储空间的需求,于是就导致了这20位地址编号必须进行分时传送

工作过程
首先在行选通信号作用下,高11位地址(211即为2048)经过地址线输入,并进行一次复制,将这两个相同的行地址分别保存在行地址锁存器中和最后读出行地址锁存器中,此指定行地址会把在DRAM阵列的2048行中所指定的那一行的所有存储单元的数据(即512 x 4位的数据)都先读入SRAM中暂存

然后在列选通信号下,低9位地址(29即为512)经过地址线输入,保存在列地址锁存器中,在读命令有效时,存储在SRAM的512 x 4位的数据中的某一个4位数据就会被列地址选中,传送到数据总线上

下一次读取的时候,CDRAM 芯片会先将从11位地址线输入的行地址与最后读出行锁存器中的内容进行各个位的比较,如果比较相同,说明此次所需要的4位数据和上一次读出的4位数据在同一行,此时就比较简单了,表明需要获取的数据一定还在SRAM中,根据列地址进行选中SRAM中对应的那4位数据即可,效率高;如果比较不同,则需要重新去DRAM阵列中去寻找,并更新SRAM中存储的所有数据和最后读出行地址所存器中的内容,最后送出指定那4位数据

效果
CDRAM使用512 x 4位 的SRAM Cache保存上一次取出数据所在行所有数据的方法,使得当CPU需要对连续的属于同一行的数据进行读取的时候,只需要连续变动那9位的列地址即可实现,这是猝发式读取,对于成块的传送的效率提高十分有利

同时,看图可知,芯片中的数据输出路径(由SRAM到I/O)与数据输入路径(由I/O到读放大器和列写选择)是分开的,这就允许在写操作完成以后,可以立即启动对同一行的读操作,而且在SRAM读出数据期间可以同时对 2048 x 512 x 4位 的DRAM阵列进行刷新操作(刷新就是一个写数据的过程)

高速缓存存储器Cache

未加入Cache之前,存储系统面临的问题

  • 问题1与Cache
    • 由于在多体并行存储系统中,由于I/O设备向主存请求的优先级会高于CPU访存的优先级,于是就会出现CPU等待I/O设备访存的情况出现,为了避免这个问题,我们可以在CPU和主存之间加入一级缓存,这样,主存就可以将CPU需要的信息提前送入缓存,一旦主存和I/O设备进行数据交换的时候,CPU可以之间去这个一级缓存中去数据,而不是进行等待,而且根据程序的局部性原理,只要将CPU近期要用到的程序和数据提前送到Cache中,就可以实现CPU在一定时间内只会访问Cache
    • 程序的局部性原理
      • 时间的局部性:当前正在使用的指令和数据,在不久的将来还会被使用到
      • 空间的局部性:当前正在使用的指令和数据,在不久的将来与其相邻的指令和数据很可能会被使用
  • 问题2与Cache
    • 主存和CPU速率方面的更新速度是不一样的(差值为一个剪刀差),这就导致了主存速度为一个机器的瓶颈,于是,我们提出了层次结构,即在主存和CPU之间加入一个高速缓冲存储器Cache,为了解决主存与CPU速率的不匹配的问题

Cache的工作原理

Cache - 主存存储空间

  • 主存

    • 主存由2n个存储单元组成(即每一个存储单元具有唯一的n位地址进行标识),将主存分为若干块,每一块中包含若干个存储单元,这就把给定的一个主存地址分成了两段,高m位标识主存块地址,低b位标识块内地址,2m即为主存的块数,2b即为块的大小(即每一个块内存储单元的个数)
  • Cache

    • 缓存也划分为若干块,每一个块内包含若干个存储单元,这就把给定的一个缓存地址分成了两段,高位c位标识缓存块地址,低b位标识块内地址,2c即为缓存的块数,2b即为块的大小(即每一个块内存储单元的个数),主存块大小和缓存块大小是完全相同的,而缓存的空间大小必然是小于主存的所以就会导致2c要远小于2m,即缓存块数要远远小于主存块数
  • 主存块与缓存块

    • 如果主存块已经调入了缓存块,则称主存块与缓存块建立了对应关系,由于缓存的块数远小于主存的块数,于是一个缓存块不可能唯一地,永久得对应于一个主存块,每一个缓存块会设置一个标记(该标识的内容相当于存储块的编号),用来标识当前存放的是哪一个主存块,CPU读信息的时候,要将主存地址的高m位(或者m位中的一部分)与缓存块的标记进行比较,判断所读信息是否已经在缓存中了

    计算机组成原理——存储器(Memory)_第30张图片

Cache效率

  • 命中率

    • 在一个程序的执行期间,设Nc为访问Cache的总命中次数,Nm为访问主存的总次数,则命中率h的表达式为
      计算机组成原理——存储器(Memory)_第31张图片
  • Cache-主存系统的平均访问时间

    • 设tc为命中时的Cache访问时间,tm为未命中时的主存访问时间,1-h表示未命中率,则Cache-主存系统平均访问时间ta的表达式为
      计算机组成原理——存储器(Memory)_第32张图片
  • 访问效率

    • 访问效率e的表达式为(访问效率的最大值为1,最小值为tc/tm)
      计算机组成原理——存储器(Memory)_第33张图片

Cache的基本结构

  • Cache存储体
    • Cache存储体以块为单元与主存进行信息交换,主存大多采用多体结构且将Cache访存的优先级划定为最高
  • 地址映射变换机构
    • 负责将CPU需要访问的主存地址通过函数关系转化为对应的Cache地址,由于主存块大小和缓存块大小相等,并且块内的地址都是块的起始地址进行加上偏移量得到的,因此地址变换的重点在于主存的块号和Cache块号的转化
  • 替换机构
    • 负责解决缓存块已满后进行块替换的问题,如果Cache内容已满,就无法继续接收来自主存块的复制信息,这时由Cache内部的替换机构按照一定的算法来确定一个将Cache中的哪一个块进行替换,实现主存信息的调入

计算机组成原理——存储器(Memory)_第34张图片

存在Cache参与的内存读操作过程

任何时刻都会有一些主存块的复制体在Cache中,CPU想要读取主存信息时(CPU只有主存的地址信息,无Cache的地址信息),此时有两种情况:

  • 1.所需要的信息已经在缓存中,即可直接访问Cache,我们称这种情况为CPU访问Cache命中
  • 2.所需要的信息不在Cache中,此时需要将信息所在的主存一整个块调入Cache中(在Cache还未满的时候,如果Cache满了,要进行的是块的替换操作),同时访问所需信息,我们称这种情况为CPU访问Cache不命中

需要指出的是,Cache对于用户是透明的,即用户进行编程的时候所用到的地址是主存地址,用户不需要知道这些内存块是否已经调入了Cache中,将主存块调入Cache的工作是由计算机硬件自动完成的

存在Cache参与的内存写操作过程

写操作过程较读操作过程会相对复杂一些,因为对于向Cache块内写入的信息,必须要与被映射的主存块中保存的信息完全一致,对于进行写操作的时候,如何保持Cache中的信息和主存中的对应信息一致的问题,我们提出了写直达法和写回法

  • 写直达法

    • 又称为存直达法,即进行写操作的时候,同时将输入写入主存和Cache,这就保证了在任意时刻,主存和Cache存储的数据始终一致,但是增加了访存次数(因为每一次数据的变动都需要访问内存实现数据的同步修改),并且进行写操作的时间相当于就是CPU对主存进行写操作的时间
    • 写直达法中,由于Cache中的数据始终与主存保持一致,于是在读操作中,如果遇到替换该Cache块的情况,直接把主存块调入Cache中即可,该被替换的Cache块中的信息不需要被写入主存,即读操作不会涉及对于主存的写操作,只有写操作才会去访问主存
  • 写回法

    • 又称为拷回法,即进行写操作的时候,只会把数据写入Cache而不写入主存,直到该Cache数据要被替换的时候,才会写回主存中,可见并不是每时每刻Cache中的信息和主存中的信息都是一致的,为了对Cache中的数据是否已经同步到主存中了,Cache中的每一块都要增设一个标志位,标识该块的状态:1.清,表示主存已经与该块的内容同步了;2.浊,表示主存还未与该块的内容同步,所以在使用写回法进行写操作的时候,要将标志位设置为浊状态;在替换时把此Cache块的信息写回主存同时将标志位设置为清状态
    • 写回法中,在进行读操作的时候,如果遇到替换该Cache块的情况,需要将该替换的Cache块中的信息写入主存,即读操作可能会涉及到对于主存的写操作,但是同时在写操作过程中,并没有去访问主存,于是写操作相对于写直达法更快,而且这种方法下,对于主存的写操作只会发生在要对该Cache块进行替换的时候发生,即如果对于一个Cache块进行了多次写操作,也只需要在进行替换的时候,对主存写入一次即可,相对于写直达法减少了对主存的写操作的次数,而且进行写操作的时间就是对Cache进行写操作的时间
    • 但是对于具有多个处理器的系统(各个处理器都具有独立的Cache,且都共享主存),又会导致当一个缓存中的数据被修改以后,不仅仅是主存中对应的信息无效了,连同其他缓存中的对应信息也无效了,即使使用替换时改变主存信息的方式也无法更新其他缓存中的无效信息

Cache的改进

典型的系统中只会有一个缓存,但是为了增加Cache的级数或者是为了将统一的Cache变成分立的Cache,开始普遍采用多个Cache

单一缓存和两级缓存

  • 单一缓存
    • 指在CPU和主存之间只设置一个缓存,而且随着集成电路逻辑密度的提高,把这个缓存直接与CPU放在同一个芯片中,故又将单一缓存称为片内缓存(片载缓存),片内缓存可以提高外部总线的利用率,因为将Cache制作在芯片中以后,CPU可以直接在芯片内部访问Cache,而不必使用芯片外的系统总线资源,,外部总线可以更多地支持I/O设备与主存的信息传输,而且片内缓存与CPU之间的数据通路长度很短,大大提高了存取速度,增强了系统的整体效率
  • 两级缓存
    • 由于片内缓存在芯片内部,其容量不是很大,于是就可能导致CPU预访问的信息不在缓存中,只能通过系统总线访问内存,访问次数多了,整机的速度就会下降。为了解决这个问题,我们会在主存与片内缓存之间再加上一级缓存,即片外缓存(一般使用比主存动态RAM和ROM存取数据更快的静态RAM组成)片外缓存和片内缓存也是不使用系统总线的,使用的是一个独立的数据路径,这样CPU占用系统总线的时间就会缩短,整机工作速度有明显的提升。这种由片内缓存和片外缓存组成的Cache称为两级缓存,同时称片内缓存为第一级缓存,片外缓存为第二级缓存,随着集成技术的提高,可以实现将第二级缓存结合到处理芯片中了

统一缓存和分立缓存

  • 统一缓存
    • 指将指令和数据都存放在同一个缓存中的Cache
  • 分立缓存
    • 指将指令和数据分别存放在两个缓存中的Cache,可以将Cache细分为指令Cache和数据Cache
  • 采用何种缓存时,需要考虑的要素
    • 1、主存结构
      • 如果主存是统一的,即指令、数据存储在同一个主存中,则应该相应地采用统一缓存,如果主存是分立的,相应地应该采用分立缓存的Cache
    • 2、机器对指令执行的控制方式
      • 如果机器采用的控制方式为超前控制(指在当前指令执行过程尚未完成的时候就提前将下一条准备执行的指令取出,这个过程称为超前取指或者指令预取)或者流水线控制(实质上为多条指令同时执行的控制方式,可以视为指令流水)方式,一般采用分立缓存,因为超前控制和流水线控制分别强调的指令的预取和指令的并行执行,都对取出指令这个操作的效率有较高的要求,如果采用的是统一缓存,则可能会出现取指操作和执行过程对统一缓存的争用,而一般是把执行过程中相关的操作的优先级设置得要高于取指操作的优先级,这样就会导致取指请求被暂时等待,明显取指操作的效率就降低了,可能会影响到超前取指和指令流水的实现

Cache的主存地址映射

每一个Cache块都具有一位有效位,用来标识该Cache块中的信息是否有效(数值为1标识有效,数值为0标识无效),比如在初始时刻,Cache还没开始复制主存中的信息,于是Cache中每一个块的有效位的数值应该都是0

直接映射(一种完全固定的映射关系)

  • 原理
    • 每一个主存块只与一个缓存块相对应,一个缓存块可以对应多个主存块,映射关系为:i = j mod C
      其中,i为缓存块号(即为缓存块的地址对应的十进制数,从零开始编号),j为主存块号(即为主存块的地址对应的十进制数),C为缓存块数
    • 前面我们对于的缓存地址和主存地址进行了划分:给定的一个主存地址分成了两段,高m位标识主存块地址,低b位标识块内地址,2m即为主存的块数,2b即为块的大小(即每一个主存块内存储单元的个数);给定的一个缓存地址分成了两段,高位c位标识缓存块地址,低b位标识块内地址,2c即为缓存的块数,2b即为块的大小(即每一个缓存块内存储单元的个数)
    • 现在我们对于主存块进行进一步的划分,把高m位细分位高t位和低c位
      • 低c位即为该主存块对应的Cache块的地址,因为进行取余运算即是对主存块的地址取低位二进制数值的过程,而这低c位就是取余后被取出的二进制数值
      • 高t位为主存块标识,由于每一个Cache块都会对应多个主存块,所以当我们仅仅拿到一个主存地址的c位部分数据的时候(即这个主存块对应的那个Cache块的地址),无法是否该Cache块正在存储的就是CPU需要访问的那个内存块的地址(可能是其他内存块的地址),我们就需要使用这t位标记位的按位比较,实现进行进一步的校验。一般会在Cache块复制主存块信息完毕以后,把被复制的主存块的标识填入该Cache块的t位标记位中,用来标识当前Cache块中存储的信息是属于哪一个主存块的
    • 一个主存地址的组成
      • t位的主存字块标记 + c位的Cache字块标记(t+c=m) + b位的字块内地址
      • 进行取余的运算的时候,是把 主存地址的 t 位的主存字块标记 + c 位的Cache字块标记 整体对应的十进制数(主存块号) 对 缓存块数进行取余, 结果为 c 位的Cache字块地址(缓存块号)
    • Cache的区域划分
      • 将Cache划分成成2c个缓存块
  • 特点
    • 缺少灵活性,每一个主存块都必须固定地对应某一个缓存块,及时Cache中的其他块是空的(即无效位数值为0),也不能进行使用,这会使得Cache中的空间不能得到有效利用,如果程序恰好要访问的主存块都映射到同一个Cache块上,则就要不断地进行Cache块的替换,降低了命中率
    • 在多层次的Cache结构中,在靠近CPU的Cache层次,要求的是高速度,于是一般采用直接映射的方式

计算机组成原理——存储器(Memory)_第35张图片
计算机组成原理——存储器(Memory)_第36张图片

全相联映射(灵活性大的映射关系)

  • 原理
    • 全相联映射允许主存中每一字块都可以映射到Cache中的任何一块上面,所以这里不描述主存块与Cache组的映射关系,这种映射方式可以从已经被占满的Cache中选择出任一旧子块进行替换
  • 特点
    • 这种方式相较于直接映射提高了命中率,缩小了块冲突率,但是同时其主存子块标记的位数从t位增加到了t+c位(m位的主存块号),即访问Cache块时需要按位比较t+c位才能确定所要访问的主存地址的信息已经存在于该Cache块中(必须要对每一个Cache的标记位都进行比较,因为目标主存块可能会与任何一个Cache块形成映射关系)。这种比较通常需要采用"按内容寻址"的相联存储器来实现
    • 在多层次的Cache结构中,在远离CPU的Cache层次,对速度的要求不高,对Cache利用率的要求高,于是一般采用全相联映射的方式
      计算机组成原理——存储器(Memory)_第37张图片

组相联映射(上述两种映射方式的折中)

  • 原理

    • 组相联映射为上述两种映射方式的折中,将Cache划分为Q组,每一组有R块,并且有主存块与Cache组的映射关系:i = j mod Q
      其中,i为缓存组号,j为主存块号,Q为缓存组数

    • 类比直接映射来说,组相联映射中将原来Cathe缓存块地址(t+c位)变成了组地址(q位,qq为Cathe缓存组的个数
      计算机组成原理——存储器(Memory)_第38张图片

    • q = c - r的数学原理

      • q这个数为一个主存地址中组地址部分的二进制位数,于是我们可以知晓,一共具有的组地址数目(即组的数目)为2q个,同时由直接映射可知,c这个数为一个主地址中缓存块地址部分的二进制位数,于是一共具有的缓存块地址数目(即缓存块数目)为2c个。此时将 缓存块数目2c 除以 缓存组数目2q 即为每一个缓存组中的缓存块数目2c-q,同时r = c - q,于是2r即为组中的Cathe缓存块的个数
    • 组相联映射的思路就是先使用直接映射,即主存块可以先经过主存块与Cache组的映射关系i = j mod Q映射到一个确定的缓存组上,然后再使用全相联映射,对于这个缓存组中的任一缓存块,这个主存块都可以进行映射,特别地,如果将r = 0,则为直接映射,如果将r = c,则为全相联映射,即组相联映射的性能以及复杂性介于直接映射和全相联映射两者之间

  • 特点

    • n路组相联映射
      • "n"指Cache缓存内部进行分组以后,每一个组中具有n个Cache块。在多层次的Cache结构中,在稍微远离CPU的Cache层次,一般采用组相联映射的方式,比如两路组相联、四路组相联或者八路组相联
    • 与直接映射相比
      • 一个块可以与多个Cache块形成映射关系,提高了灵活性和Cache的利用率
    • 与全相联映射相比
      • 判断目标主存块是否已经调入Cache中,可以先进行主存块号的映射,先确定某一个Cache组,再使用主存地址的主存字块标识和该组中的所有Cache块的标识进行比对,如果存在相同的标识,则找到了目标主存块。不需要与像全相联映射一样对全部Cache块标识进行比较,组相联映射缩小了比较范围,提高了运行速率
  • 一个主存地址的组成

    • s(即 t+r )位的主存字块标记 + q(即 c-r )位的Cache组地址 + b位的字块内地址
    • 进行取余的运算的时候,是把 主存地址的s(即 t+r )位的主存字块标记 + q(即 c-r )位的Cache组地址(主存块号) 对 缓存组数取余, 结果为 q(即 c-r )位的Cache组地址(缓存组号)
  • Cache的区域划分

    • 将Cache划分成具有2q个组,每一个组中划分成具有2r个块

Cache的替换策略

替换

当新的主存块需要调入Cache中,同时Cache又已经被旧有的主存块占满了,此时就需要进行Cache块的替换操作,这就产生了替换策略(算法)问题,即如何挑选被替换的Cache块的问题。在直接映射的Cache中,对于一个内存块来说,只有一个Cache块与之对应,于是映射的策略很简单,但是对于组相连和全联映射的Cache中,主存块可对应于多个Cache块,于是就需要使用一些可靠的替换算法进行选择。理想的算法是将未来很少用到的或者是很久才会用到的数据块替换出来,但是实际上是非常难做到的

替换策略

  • FIFO(First In First Out 先进先出)算法

    • FIFO算法会选择最早调入的Cache块进行替换,这个算法不需要记录各个Cache块的使用情况,比较容易实现,开销小,但是没有根据访存的局部性原理,所以不能提高Cache的命中率,因为最早调入的信息可能以后还要用到,比如循环程序
  • LRU(Least Recently Used 近期最少使用)算法

    • LRU算法比较好地利用访存局部性原理,替换出近期用得较少的Cache块,这个算法需要随时记录Cache中各个块的使用情况(为了记录Cache各个块的使用情况,设置了一个调用情况记录表,称为LRU目录),以便确定哪一个块是近期最少使用的Cache块,实际为一种推测方法,比较复杂,所以一般使用其的简化方法,即只记录每一个块最近一次的使用时间,LRU算法的平均命中率比FIFO的高
  • 随机法

    • 顾名思义,就是随机得确定被替换的块,可用使用一个随机数生成器产生一个随机的被替换的块,但是由于该算法也没有根据访存的局部性原理,于是也不能提高Cache的命中率

辅助存储器(还未补全,尽请期待)

辅助存储器不能直接与CPU进行数据交换

磁表面存储器

  • 技术指标
    • 记录密度
      • 道密度Dt:在硬盘的径向方向上,单位长度具有的磁道数量
      • 位密度Db:单位长度的磁道保存的二进制信息数目
    • 存储容量
    • 平均寻址时间
      • 寻道时间+等待时间
    • 数据传输率
      • 位密度*旋转速度
    • 误码率
      • 出错信息位数除以读出信息的总位数
  • 磁记录原理
    • 写操作原理
      • 由于电磁感应,可以通过读写头对载磁体表面的磁层进行磁化,磁化方向的不同就可以区分存储的是1还是0
        计算机组成原理——存储器(Memory)_第39张图片
    • 读操作原理
      • 由于已经被磁化的磁层进行运动,就会在读写头处,由于切割磁感线而产生感应电路,根据电势的变换,就可以确认磁载体中保存的是1还是0

硬磁盘存储器

  • 分类(按照磁头是否固定)
    • 固定磁头
      • 盘片旋转,磁头不动,这样每一个磁道都需要一个磁头,磁头数量庞大,但是速度较快
    • 移动磁头(常用)
      • 盘片不动,磁头径向移动
  • 分类(按照硬盘的盘片是否可以更换)
    • 可换盘
    • 固定盘(常用)

你可能感兴趣的:(嵌入式硬件)