您的位置: 网站首页 > 程序开发 > 汇编语言与微机原理教程 > 第4章 内部存储器的结构与原理 > 【4.2 80x86系统存储器结构】

4.2 80x86系统存储器结构

 

4.2  80x86系统存储器结构

4.2.1  CPU与存储器的连接

对于半导体存储器器件而言,低价格、大容量、高速度是一组永恒的矛盾,用单一工艺制造的半导体存储器难以同时满足上述3方面的要求。解决这个问题的有效方法就是发挥不同存储器件各自的长处,采用多层次的存储系统。

所谓多级存储体系就是把几种不同容量、速度的存储器合理地组织在一起,使它们能较好地同时满足大容量、高速度、低价格的要求。当然,这是以增加技术复杂程度为代价的。

如图4-5所示是存储系统的层次结构示意图。该系统由高速缓存、主存、辅存3类存储器组成。3类存储器构成了两个层次的存储系统。

4-5  存储器系统的层次结构

1)高速缓存主存层次。

cache由静态RAM(即SRAM)构成,速度可与CPU速度相匹配,容量很小,但可存放一小段时间内CPU用到的指令和数据。这样,CPU在这一小段时间内可以不必与主存交换信息而直接访问cache,从而提高了指令的执行速度。CPU访问内存储器,同时将地址码送到cache和主存;若在cache中找到所需的内容,则访问“命中”,信息在cache中存取;否则访问“失败”,CPU就将所需信息页从主存装入cache并进行数据存取。cache访问的命中率随应用程序而异,高的达到90%左右。从系统的角度看,cache—主存层次的速度接近于cache,而容量则是主存的容量。

主存一般由大容量的动态存储器组成,它的单位成本低于cache,速度相对较慢。cache和主存构成计算机的内存储器。cache与主存之间以页为单位进行读/写操作。

处理器需要读取指令或数据时,将主存中该指令或数据所在的页整体同时读入cache。这样,当处理器需要再次读入该页内的指令和数据时,可以从cache内快速读取,从而加快程序的执行速度。由于程序具有局部性的特征,在一个短的时间段内,程序和数据集中在一个小的存储区域内,因此使用cache可以有效地提高系统性能。

可以看出,这一层次主要解决存储系统的速度问题。

2)主存辅存层次。

辅助存储器由大容量的磁表面存储器或光存储器构成,它的显著特征是具有很低的位存储价格。辅助存储器上存储着大量的程序和数据,在大部分时间里,它们处于静止状态,也就是没有被使用。处理器仅把目前使用的程序和数据装入主存。辅存和主存之间以页为单位进行读/写交换。

显然,这一层次主要解决存储系统的容量问题。

以上两个层次的组合本质上来说是充分利用cache的高速度及辅助存储器的大容量和低成本,使存储系统较好地解决容量—速度—价格之间的矛盾。主存则用来弥补辅存不能随机存取,以及辅存与cache速度差异过大的不足。

4.2.2  高速缓存系统

1cache的工作原理

微机均设置有一级高速缓存(L1 cache)和二级高速缓存(L2 cache)。一级高速缓存直接嵌入CPU芯片内部,又称为内部高速缓存(internal cache)。其速度极快,但容量较小,一般为8KB64KB。在CPU外部、位于主板上的高速缓存称为二级高速缓存,又叫做外部高速缓存(external cache)。L2 cache可以人为升级,其容量从256KB到几MB不等;Pentium II/Pentium III已把CPU内核与二级缓存一起封装在一个金属盒内。

现在微机把二级缓存也集成到芯片内,片外主板上安置三级缓存。而IA-64架构的Itanium 2(安腾2)则把一、二、三级缓存都集成到微处理器芯片内。

cache使CPU访问内存的速度大大加快。读取数据时,CPU首先在一级缓存中寻找数据,如果找不到,则在二级缓存中寻找;若数据在二级缓存中,在传输数据的同时,装入并修改一级缓存的相关内容;若数据既不在一级缓存也不在二级缓存中,则从内存中读取数据并修改两级缓存。

访问存储器时,CPU输出访问主存的地址,经地址总线送到cache的主存地址寄存器MAcache—主存地址转换机构从MA获得地址并判断该单元的内容是否已经在cache中存储,如在则称为“命中”,立即把访问地址转换成其在cache中的地址,随即访问cache存储器。如果被访问的单元内容不在cache中,称为“未命中”,CPU直接访问主存,并将包含该单元的一个存储页的内容及该页的地址信息装入cache中;若cache已满,则在替换控制部件的控制下,按照某种置换算法将从主存中读取的信息页替换cache中原来的某页信息。

由程序访问的局部性原理可知,CPU访问的内容在多数情况下已经复制于cache中,64KB cache可以缓冲4MB的主存,命中率一般在90%以上,因此CPU的读/写操作主要在CPUcache之间进行。

2cache的基本操作

完成高速缓存操作的具体实现途径是CPUcache—主存。CPUcache之间按行传输,cache—主存之间按页(又称块)传输;行或页的大小因计算机系统而异,一般为连续256位,即32B;页的大小与cache—主存之间的地址映射方式相关,通常为256B的整数倍。

cache和其他存储器一样,有读和写两种基本操作。

1)读操作。

CPU将主存地址同时送往主存和cache,启动存储器读,如果命中cache,则从cache中读出数据到数据总线,并立即进行下一次访问操作;如果未命中cacheCPU就从主存中读出数据,同时cache替换部件把被读单元所在的存储块从主存复制到cache中。

2)写操作。

写操作与读操作有很大的不同,它要对被写单元设置新值。因此,当对cache的写操作命中时,如何确保它与相对应的主存单元内容之间的一致性是个至关重要的问题。通常有3cache写入方法。

通写(write-through)。即每次写入cache时,同时也写入主存,使主存与cache对应单元的内容始终保持一致。这种方法比较简单,能保持主存与cache副本的一致性,可随时修改cache内容,不会造成数据丢失;缺点是每次写入cache都要插入慢速的访问主存操作,影响工作速度。

改进通写(improve write-through)。如果对cache写入的后面紧接着进行的是读操作,那么在主存写入完成前即让CPU开始下一个操作,这样就不致于浪费太多的时间;如果前后两个操作都是对cache写,或者虽然是读,但对cache的寻址没有命中,则仍需在CPU写主存时插入等待周期。这种方法与通写相比,有利于改善系统性能。

回写(write-back)。该方法不是每次写入cache后就立即向主存写入,只是在相应内容被替换出cache时才考虑向主存回写:如果cache行数据在它存在期间发生过对它的写操作,那么在该行被覆盖(替换出cache)前必须将其内容写回到对应主存位置中;如果该行内容没有被改写,则其内容可以直接淘汰,无须回写。这种方法的速度比通写法快,被普遍采用;但结构复杂,在回写前cache副本与主存的对应内容不一致。

3.地址映射

为了保证cache/写操作的正确有效,必须在cache中的存储块与主存中的存储块之间建立起对应关系。按某种函数关系把主存单元地址映射到cache中并进行定位,称为地址映射。在程序运行中,把主存地址变换为cache地址,或者相反地将cache地址变换为主存地址,这个过程称为地址变换。地址映射有直接映射、全相联映射和组相联映射3种。

1)直接映射。

直接映射法规定:主存中的一页只能进入与它页号相同的cache页中。

每个主存地址映射到cache中一个指定地址的方式称为直接映射(direct mapped)。cache空间小,地址位数少,页数也少,主存空间大,地址位数多,页数也多;直接映射是将主存中的页号(页地址)对cache中的页数(页的总数)取模,得到其在cache中的页号。这相当于将主存的空间按cache的大小分区,每个区内相同的页号映射到cache中的同一页号。

直接映射最简单,页调入cache时不涉及替换策略问题,地址变换速度快。但直接映射方式页冲突概率高,当程序反复访问相互冲突的页中的数据时,cache命中率急剧下降,cache中有空闲页也无法利用。

2)全相联映射。

主存中的每个页可映射到cache中任意一个页的位置上,称为全相联映射(full association)。全相联映射具有相当高的cache命中率,只有在cache中的页全部装满后才会出现页冲突,页冲突的概率低,cache利用率高。

全相联映射访问页中的数据时,页地址要与cache页表中的所有地址标记进行比较以确定命中与否,查找的速度慢;数据页调入时存在复杂的替换策略问题(数据页调入cache中的什么位置、cache满时将哪一页调出送回主存等),所有的比较与替换策略要用硬件实现以体现cache的高速度,控制复杂,实现起来较困难。

3)组相联映射。

组相联映射将cache和主存各自分为若干组,各组之间采用直接映射,组内各页之间采用全相联映射,主存中的某一存储页可调入cache中一个对应组内的任意页中,它是全相联映射和直接映射的一种折中,组数为1时就成了直接映射,分组数和页数相等时就成了全相联映射。

80486一级8KB cache采用两组相联映射法,使其内存性能大大优于80386;而Pentium Pro以后对256KB1MB的二级cache采用4组相联映射法,其内存性能更佳。

4.替换规则

在对存储器进行读/写操作的过程中,当需要从主存复制新页到cache时,若cache已满,就必须在控制部件控制下用新页替换cache中的旧页。替换按一定的规则进行,这些规则称为替换策略或替换方法。替换规则应尽量使被替换下的页在下一时间段内最少用到。常用的替换规则有以下两种:

1)先进先出规则(FIFO)。

FIFO规则总是把最先调进cache的页替换出去。FIFO容易实现,无须随时记录各个数据块的使用情况。这种方法实现简单,但不够合理,因为最早进入的页仍然可能是现在频繁使用的页,这是FIFO规则的缺点。

2)近期最少使用规则(LRU)。

LRULeast Recently Used)规则是将cache中近期使用最少的信息块替换出去。LRU规则需要随时记录cache中各个块的使用情况,以确定哪个块是近期使用最少的块。LRU的命中率比FIFO高;加大分组容量能提高LRU规则的命中率。这种算法比较合理,但是实现起来稍微复杂一些。

5cache和主存一致性问题

使用高速缓存之后,一项数据可能同时存储在两个地方,处理器把数据写入cache,尚未写入主存时,就产生了cache与主存内容的不一致性。

解决这个问题可以采用以下两种方法:

1)写回法(write back)。

处理器执行写操作时,信息只写入cache,该页被替换时,才将它写回主存。

2)写直达法(write through)。

处理器执行写操作时,信息在写入cache的同时也写回主存。

使用写回法,一个主存页面调入cache后最多回写一次(内容未修改则不需要写回),节省了写回时间,但是一致性保持不如写直达法。

6.突发总线周期(brust bus cycle

主存和cache之间以页为单位进行信息交换,这意味着每次传送都是对连续的若干字节进行的。为了缩短传输时间,新型主存器件都支持突发总线传输方式。

所谓突发总线传输就是向主存储器发送起始地址之后,连续传送多个字的数据。以Pentium为例,它的cache每页为64b,与主存之间可以同时传输64b也就是8B信息。主存页调入cache时,管理逻辑向主存发出该页的起始地址,同时发出突发总线请求信号。主存在收到上述信号并适当延时之后,在连续的多个周期内每次发送8B64b)信息,最终把一页内容写入cache

使用突发总线传输方式减少了发送地址信号和重复启动读/写的时间,可以获得很高的数据传输速率。

4.2.3  虚拟存储系统简介

虚拟存储技术在“主存—辅存”层次上,将主存和辅存空间的一部分统一编址,看作一个完整的虚拟存储空间,使程序可以有比主存大得多的运行内存空间,运行时又能获得接近于主存的存取速度。

现代微型计算机功能强大,支持多任务和多媒体的广泛使用,系统程序和应用程序使用的内存数量越来越大,由于成本的原因,主存物理容量配置难以满足上述要求。通过虚拟存储技术可以解决成本与容量的问题。

微型计算机每个任务的运行都要向操作系统申请使用内存,在任务注销后将内存释放。由于每个任务需要的内存数量各不相同,系统运行一段时间之后,主存空间将出现许多碎片。清理这些碎片需要移动正在使用的内存片,这会带来许多复杂的问题。使用虚拟存储技术可以有效地解决碎片问题,这也是虚拟存储技术被广泛使用的原因之一。虚拟存储管理同时也有效地解决了多个任务之间、用户任务与操作系统之间存储空间的隔离和保护问题。

虚拟存储器的管理一般由硬件实现的存储管理部件MMU和操作系统软件共同完成。大多数的虚拟存储管理使用3级地址空间:逻辑地址、线性地址、物理地址。

逻辑地址:虚拟存储器的辅存部分也像内存一样供用户使用,编程时面向程序的需要,而不必考虑程序将来在主存中的实际位置,因而称这种指令地址为逻辑地址,又叫虚地址。CPU按虚地址访问的空间可达整个被用到的辅存,虚地址所对应的存储空间称为“虚存空间”或“逻辑空间”。其大小取决于计算机访问存储器的能力,由指令的地址位数和地址形成机构等决定。

物理地址:实际主存单元的地址称为物理地址,又叫“实地址”。实地址对应的是“主存空间”,又叫“物理空间”。显然,虚地址的寻址范围比实地址大得多。

CPU执行程序时,需要将程序提供的虚地址变换为主存的实地址。通常先由存储管理部件MMU判断该地址的内容是否已调入主存中,若在主存中则通过地址变换机制把虚地址变换为实地址,然后访问主存;若尚未调入主存,则产生缺页中断,以页为单位调入主存或实现主存—辅存内容调换。

4.2.4  虚拟存储器地址映射

1.段存储管理

段存储管理完成逻辑地址向线性地址的转换。

在程序员使用的地址空间里,每个存储单元可以表示为“段名:段内偏移地址”的形式。这样的地址称为逻辑地址。

8086 CPU不支持虚拟存储管理,段寄存器直接记录了该段的起始地址信息。将段起始地址与偏移地址相加,就得到了该存储单元的物理地址。

80386开始的32位微处理器中,段的信息被记录在段描述符中,包含32位段起始地址、20位段界限值(段长度)、4位段类型、2位段描述符优先级,以及其他信息共64位。操作系统所使用段的段描述符顺序存放,组成全局段描述符表(GDT),该表的首地址记录在全局段描述符表寄存器GDTR中。每个任务所使用段的段描述符组成局部段描述符表(LDT)。

在整个系统中,GDT表只有一张,LDT表每个任务一张。但是从任务的角度看,段描述符表只有两张:GDTLDT

16位段寄存器中不再直接含有段起始地址的信息,其中的1位段描述符表指示器记录了该段是在GDT=0)中还是在LDT=1)中,13位段描述符表索引记录了该段描述符在表中的顺序编号,另外2位存储了该任务的请求优先级(RPL)。这16位信息称为段选择子,使用段选择子和2张段描述符表可以把逻辑地址转换成线性地址。逻辑地址到线性地址的转换如图4-6所示。

4-6  逻辑地址到线性地址的转换

GDTLDT两张表格存储在主存储器中。在保护状态下,每条指令的执行都伴随着逻辑地址向线性地址的转换过程。为了提高指令执行速度,在32位微处理器内部除了在段寄存器中存有段选择子之外,还增设了与段寄存器对应的段描述符寄存器。在装载段选择子的同时,主存中对应的64b段描述符信息同时进入该寄存器。如图4-6所示的由段选择子向段基地址的转换过程仅仅是原理性的说明,段基地址可以从段描述符寄存器中直接获得,并不存在实际的查表过程。

从理论上来说,16位段选择子可以选择两张表中共213×2=214个不同的段。每个段最大可达232B。因此,通过段存储管理最多可管理232×214=246B=64TB的虚拟地址空间。

2.页存储管理

线性地址空间仍然是一个虚拟的地址空间,物理地址空间是实际的存储空间,它们都划分成若干大小相等的页。页存储管理部件负责完成线性地址向物理地址的转换。

线性地址空间一般远大于实际的物理地址空间,页存储管理部件需要决定虚拟内存的哪些页调入实存,其余的则保存在辅助存储器中。

80386为例,每个页大小为4KB,线性地址空间里每个页面的信息记录在一个32位的页表项中,包括32位物理地址的高20位(低12位与线性地址的低12位相同)、目前是否在实存中,以及该页的使用情况等相关信息。每1024个页面组成一个页组,它们对应的页表项构成一张页表,4KB大小的页表本身构成了一个特殊的页。

系统用一张页组表记录所有页组的信息。页组表由1024个页组目录项组成,32位的页组目录项具有与页表项类似的格式,只不过它记录的是1024个特殊的页—页组表的相关信息。

于是,32位线性地址可以划分如下。

·    10位页组目录项索引:记录该线性地址单元所在的页组。

·    10位页表项索引:记录该线性地址单元在该页组的哪一个页中。

·    12位页内偏移地址:记录该线性地址单元在该页内的相对位置。

线性地址向物理地址的转换通过查两次表实现(如图4-7所示)。

·    用高10位查页组目录项表,得到该页组的页组表首地址。

·    用次10位在刚得到的页组表中查到该页的起始物理地址。

·    页的起始物理地址加上低12位的页内偏移地址,得到完整的32位物理地址。

4-7  线性地址到物理地址的转换

页组目录项表的首地址存放在处理器的CR3寄存器中。由于页表和页组目录项表的每一项占用48位,所以210位的索引值都要乘以4再与表的基地址相加,就可找到该目录项。

系统中应有一张页组目录项表,最多有1024张页表,这些表存放在主存储器中。实际使用时,把目前经常使用的表项转储在处理器内部称为转换检测缓冲器(TLB)的小型高速缓存中,以提高查表速度。

Pentium 开始的微处理器中可以使用页目录指针表(PDPT),如果仍然以4KB为一页,32位线性地址被划分为4部分。

·    2PDPT项号用来查PDPT表,得到页目录表的首地址。

·    9位页目录项号用来查页目录表,得到页表的首地址。

·    9位页面号用来查页表,获得24位的页基地址。

·    24位页基地址与12位页内偏移地址组合,得到36位物理地址。可以看出,它的基本方法与上面所述是一致的。