02计算机组成原理-虚拟存储器
前言
关于虚拟存储器我们还会在操作系统那里讲到,所以这里只是简单让大家了解一下就行了。
1.虚拟地址
我们知道存放在外存上的可执行文件,调入到内存中才能运行。外存的文件调入到内存之后会构成进程的内存映像,进程就是运行的程序,进程的内存映像包括数据段 代码段 进程控制块 堆(用于存放动态分配的变量) 栈(用于实现函数调用),一个程序要运行就要调入上述这些东西。这些内容会占用一定的内存空间,假设程序占:XGB,内存:12GB,它们的关系是X可能大于12等于12小于12,比如玩一些大型游戏,战地,王者荣耀,刺客信条这种,那这些程序这么大内存都装不下了,那是怎么解决的呢?此外,程序调入内存会占用一定的内存空间,它会有自己的内存地址,我们称为物理地址(真实存在的地址)。相对应的还有个逻辑地址,我们知道高级语言的代码转换为可执行文件的过程要经过编译,链接,装入,在编译后会生成一个.o文件,这个文件就编译为一块模块,很多个文件就有很多个模块,而每一个目标模块都会从0开始编址,这个地址就是相对地址(逻辑地址)也称虚拟地址。对于用户程序员来说见到的是虚拟地址。
现在来看XGB<12GB但是内存中没有连续的空间给X了,我们会将内存和程序都分页,有点类似与Cache的分块,虚拟空间和物理内存分页,页的大小是不确定的,由操作系统决定,分页之后把虚拟空间中的地址一页一页地往内存里面放,这样就不要求有连续的空间了,这样虚拟地址就可以分为虚拟页号+页内地址,物理地址可以分为主存页号+页内地址。这样CPU需要访问一个数据,给出这个数据的虚拟地址,根据这个虚拟地址的高位找到虚拟页号,通过虚拟页号找到主存页号,由于虚拟空间和物理空间中页里的数据是相同的,所以找到主存页号后直接根据页内地址找到对应的物理地址就可以了。这就是把虚拟地址转换为物理地址的过程。
那怎么通过虚拟页号找到主存页号呢?通过虚拟页号找到主存页号,需要依靠页表。页表由操作系统建立和维护,并且存放在内存中,页表中记录了虚拟页号与主存物理页号的对应关系。还有一个寄存器叫页表基址寄存器(PTBR),它保存的是页表在物理内存中的起始地址。
2.虚拟存储器技术
我们在1中已经知道了如何在内存不连续的时候存放从外存调入进来的数据,现在我们来看如何在内存放不下大数据的时候该怎么解决。
这个时候需要虚拟存储器技术,程序在运行的时候不会所有的数据都要调入进去,比如你玩英雄联盟,玩海克斯大乱斗就把关于这部分的数据调入进去,冲皮肤的时候就把冲皮肤的模块功能调入进去。所以说把内存当作外存的缓存。现在我们要运行程序中对应的模块,就把这个模块对应页面调入进内存中,不用的时候就替换出来,给用户的感觉就是内存好像是够用的。这样就解决了大的数据要调入内存中的时候,内存不够的问题。虚拟存储器技术相当于把内存和外存统一编址了。
CPU 要访问一个数据的时候会给出一个虚拟地址,将虚拟地址拆分为虚拟页号和页内偏移。根据虚拟页号去查页表,如果这个页已经被调入内存,就将有效标记位记为 1,此时用页表中查到的物理页号加上不变的页内偏移,就得到物理内存地址。如果该页没有调入内存,就将有效标记位记为 0,此时会触发缺页中断,页表项中存放的是该页在外存中的地址。如果内存中的页面已满,就使用页面替换算法换出某一页,这一过程和 Cache 的替换机制很相似。

CPU整个找数据的过程为:CPU给出虚拟地址,这个虚拟地址可以被拆分成高位的虚拟页号和低位的页内地址,得到这个虚拟地址后去访问页表(因为页表在主存中,所以这相当于一次访存),根据页表和虚拟页号找到对应的主存页号再加上页内地址找到对应的物理地址,拿到这个物理地址去访问Cache,如果Cache未命中访问主存...
虚拟存储器机制为程序员提供了一个极大的虚拟(逻辑)地址空间,它是主存和磁盘I/O设备的抽象。虚存机制给每个进程带来了一个假象,好像每个进程都独占使用主存,并且主存空间极大。
(1)每个进程具有一致的虚拟地址空间,从而可以简化存储管理。
(2)它把主存看成是磁盘存储器的一个缓存,在主存中仅保存当前活动的程序段和数据区,并根据需要在磁盘和主存之间进行信息交换,通过这种方式,使有限的主存空间得到了有效利用。
(3)每个进程的虚拟地址空间是私有的,因此,可以保护各自进程不被其他进程破坏。
虚拟存储器机制中,每个源程序经编译、汇编、链接等处理生成可执行的二进制机器目标代码时,每个程序的目标代码都被映射到同样的虛拟地址空间,因此,所有用户进程的虚拟地址空间是一致的。
虚拟存储器的作用:
- 虚拟地址空间与保护
每个程序拥有自己独立的虚拟地址空间,这是一个逻辑上的连续地址范围,程序的所有指令和数据都映射到这个空间中。虚拟地址空间的隔离是通过硬件和操作系统协作实现的,确保了一个程序不能直接访问到另一个程序的地址空间,从而提供了内存保护。这种隔离机制是通过内存管理单元(MMU)和页表(Page Table)实现的,MMU负责将程序产生的虚拟地址转换为实际的物理地址,同时检查访问权限,防止非法访问。 - 动态内存共享与分配
虚拟机之间的内存共享情况是动态变化的,特别是在云计算环境中,虚拟机的创建、销毁、迁移和资源调整都是常态。虚拟存储器的灵活性在于它能够动态地映射虚拟地址到物理地址,使得即使物理内存资源在不同虚拟机之间动态分配,也能确保每个虚拟机看到的是自己独立且连续的地址空间。这一特性允许高效的资源共享,同时保持了程序间的隔离和安全性。 - 编译与地址空间无关性
在编译时,程序通常被编译为使用虚拟地址,而不是物理地址,这使得程序代码可以在任何拥有足够虚拟地址空间的环境中运行,而无需预先知道物理内存布局或与其他程序的关系。这种编译时的地址空间无关性(Address Space Layout Randomization, ASLR)不仅增强了安全性,还提升了程序的可移植性和灵活性。 - 地址转换与保护机制
地址转换过程涉及到将虚拟地址转换为物理地址,这一步骤通常伴随着权限检查,确保进程只能访问其被允许的内存区域。例如,操作系统会标记某些页面为只读或不允许访问,当进程试图违反这些规则时,MMU会触发一个异常(如页面错误),操作系统则可以根据异常类型采取相应措施,如终止进程或调整内存布局。
3.MMU
地址转换通常是由内存管理单元(MMU)或类似的硬件组件完成的,它使用页表(Page Table)或其他数据结构来存储虚拟地址到物理地址的映射。页表是一个数据结构,其中包含了虚拟页号到物理页框号的映射。当进程尝试访问内存时,MMU会查找页表,找到对应的物理地址,并将访问重定向到该物理地址。
4.快表
由于页表可能非常大,并且频繁地访问页表会导致性能下降,因此现代计算机通常使用缓存技术来加速地址转换。
这种技术被称为快表(TLB,Translation Lookaside Buffer),它存储了最近使用的虚拟地址到物理地址的映射。当MMU需要查找页表时,它首先会检查TLB中是否有相应的条目。如果有,则直接使用TLB中的映射,从而避免了访问页表的高开销。
局部性原理在虚拟存储器中同样适用。由于程序在执行时通常只会频繁地访问其地址空间的一小部分(即活跃部分),因此虚拟存储器系统可以利用这一原理来提高性能。具体来说,虚拟存储器系统会将进程当前活跃的部分加载到物理内存中,并将不活跃的部分交换到磁盘上的交换空间中。当进程需要访问不在物理内存中的内存页时,会触发一个页面错误,此时操作系统会将所需的页面从磁盘加载到物理内存中,并替换出某个不活跃的页面。
5.虚拟存储器和缓存
虚拟存储器和缓存虽然在工作原理上是相似的,但由于它们的历史根源和应用场景的不同,使用了不同的术语。
页(Page)与块(Block):在虚拟存储器体系中,数据被组织成固定大小的页,这是虚拟地址空间和物理地址空间之间映射的基本单位。而在Cache中,数据通常被分成块,作为Cache与下一层存储(如主存)交换数据的单位。
缺页(Page Fault)与Cache Miss:缺页是指处理器尝试访问一个尚未加载到物理内存中的虚拟页时发生的事件,此时需要操作系统介入,将所需页从二级存储(如磁盘)加载到主存中。Cache Miss则指的是处理器在Cache中未找到请求的数据块,需从下一级存储(如主存)获取。
地址映射与转换:虚拟存储器中的地址转换过程涉及将虚拟地址转换为物理地址,这一过程通过页表(Page Table)或更高效的转换查找缓冲区(Translation Lookaside Buffer, TLB)来完成。操作系统维护页表,记录了虚拟页到物理页的映射关系。当处理器生成一个虚拟地址时,硬件(MMU)利用页表或TLB进行转换,以确定实际的物理地址。
6.当今存储层次结构
个人移动设备:在现代移动设备中,存储层次结构通常由快速但容量较小的DRAM(如LPDDR,低功耗双倍速率SDRAM)作为主存,以及更高容量但较慢的闪存(如NAND Flash)作为辅助存储。虚拟存储器技术确保了操作系统和应用程序可以高效地使用这两级存储。
服务器环境:在服务器和数据中心场景中,DRAM(动态随机存取存储器)仍然是作为高速主存的首选,而磁盘(通常是SATA/SAS SSD或NVMe SSD)或更传统的HDD(机械硬盘)用于提供大量的非易失性存储。虚拟化技术使得服务器能够高效地在多个虚拟机之间共享这些物理资源,同时保持每个虚拟机的独立地址空间。
虚拟存储器和缓存虽然在工作原理上有相似之处,但由于它们的应用场景和历史根源的不同,使用了不同的术语和配置。虚拟存储器通过页和缺页机制实现程序的地址空间与物理内存的映射,从而允许程序使用比物理内存更大的地址空间。同时,它也为操作系统提供了有效的内存管理机制,可以自动处理内存不足和内存碎片化等问题。
对于虚拟存储器更详细的介绍,我们会在操作系统当中具体的去描述。这里就不再做更详细的讲解了。大家清楚这个概念就好了。
7.并行存储器层次结构
多核多处理器(也称为多核处理器或CMP)的设计使得在一个物理芯片上能够集成多个处理器核心。这些核心能够并行执行代码,从而提高整体处理能力和效率。然而,这种并行性也带来了一些挑战,特别是当涉及到共享资源,如内存和缓存时。
缓存是处理器为了提高访问速度而设计的一种快速存储器。由于处理器访问缓存的速度比访问主存快得多,因此缓存通常用来存储处理器最近访问过的数据和指令。然而,当多个处理器核心共享缓存或主存时,就可能出现数据一致性的问题。
当两个或多个处理器核心同时访问和修改同一内存位置时,如果没有适当的同步机制,就可能导致数据不一致。这是因为每个处理器核心都有自己的缓存,并且可能同时缓存了同一内存位置的不同副本。如果两个核心都修改了自己的缓存副本而没有通知其他核心,那么其他核心在后续访问该内存位置时可能得到错误(或过时)的数据。
在支持cache一致性的多处理器系统中,数据的迁移(migration)和复制(replication)是两种关键技术,用于提高访问共享数据的性能。这些技术通过减少访问远程共享数据的延迟、减少对共享存储器带宽的需求以及降低读取共享数据时的竞争现象,来优化系统性能。
迁移(Migration):当某个处理器需要频繁访问原本存储在远端或共享存储器中的数据时,该数据会被迁移到该处理器的本地Cache中。这一过程减少了远程内存访问的延迟,同时也减轻了共享存储器带宽的压力,因为后续对该数据的访问可以直接在本地Cache中完成,无需再次访问主存。
复制(Replication):当多个处理器需要同时读取同一个共享数据项时,系统可以在每个处理器
的本地cache中都复制一份这个数据项。这样,每个处理器都可以在自己的cache中直接读取数据,而无需等待其他处理器完成读取或访问远程存储器,从而减少了访问延迟和读取共享数据时的竞争现象。
为了维护多个处理器之间cache的一致性,系统需要实现一种称为cache一致性协议(cachecoherence protocol)的机制。这个协议负责跟踪所有共享数据块的状态,并确保所有处理器都看到一致的数据视图,需要保持三个性质:
读后写一致性:
当一个处理器(如处理器P)对一个内存位置(如X)执行写操作后,紧接着又对该位置执行读操作,并且在这两次操作之间没有其他处理器对该位置执行写操作,那么读操作必须返回之前写操作所写入的值。这保证了处理器内部指令执行的顺序性,即使在单处理器系统中也很重要,因为它确保了程序按照程序员预期的顺序执行。
存储器一致性:
当一个处理器(如处理器P)对一个内存位置(如X)执行读操作,并且这个读操作是在另一个处理器如处理器Q)对该位置的写操作之后,且在这两个操作之间没有其他处理器对该位置执行写操作,那么读操作必须返回之前写操作所写入的值。这确保了多个处理器之间的数据可见性。如果没有这种一致性保证,处理器可能会读取到旧的、不一致的数据值,导致程序行为错误。
写操作的串行化:
第三个性质强调了对同一地址的所有写操作必须有一个全局一致的顺序,即使在不同的处理器上并发执行。这意味着,无论从哪个处理器的角度观察,写入操作的顺序都是确定且一致的。这是确保数据一致性的关键,因为它避免了写操作的乱序执行可能带来的不可预测状态。这避免了"写-写"竞态条件,确保了不同处理器之间的写操作不会相互干扰,也不会导致数据状态的不确定性和不可预测性。
监听协议:是实现多处理器Cache一致性最常用的方法之一。
在这种协议下,每个Cache控制器都会监听系统总线或专用的互联网络上的活动,以便及时发现对共享数据的访问请求和更新。根据监听到的信息,Cache控制器会更新其内部维护的共享数据块的状态,并在必要时采取相应的动作,如更新本地Cache中的数据副本、废弃过时的数据副本(Invalidation),或者广播自己的写操作到其他Cache以保持一致性。
常见的监听协议包括MESI(Modified, Exclusive, Shared, Invalid)和其变体MOESI(Modified, Owner, Exclusive, Shared, nvalid),这些协议通过维护数据块的多个状态来精确控制数据的读写操作,确保所有处理器看到的数据是一致的。
监听协议的优势在于它能够动态响应系统中的访问请求,减少了集中式管理的复杂性和潜在瓶颈,但其缺点是随着处理器数量的增加,总线或网络上的通信开销可能会增大,影响性能。因此,在大规模多处理器系统中,可能还会采用更为复杂的分布式一致性协议,如分布式目录协议,来进一步优化性能和可扩展性。
这节课的重点还是虚拟存储器那里,其他的了解一下即可,特别是完整的CPU的寻址,以及对于快表,页表的理解--跟Cache和主存类似。对于考研来说存储器这一章很重要,大家好好复习,下一章讲IO。大概先写这些吧,今天的博客就先写到这,谢谢您的观看。