版权归原作者所有,如有侵权,请联系我们

[科普中国]-有效虚拟地址

科学百科
原创
科学百科为用户提供权威科普内容,打造知识科普阵地
收藏

简介

有效虚拟地址一种解释是指:X64 CPU 仅支持 64 位虚拟地址中的 48 位,这 48 位虚拟地址被运行在该 CPU 上的软件使用,这主要应用在分布式操作系统或者超级计算机中。第二种解释就是指源程序的地址空间中的地址。这和源程序需要需要地址空间大小有关系。(其中源程序的地址空间叫做符号名地址空间或者名空间,它是从0号单元开始编址,并顺序分配所有的符号名所对应的地址单元,所以它不是主存中的真实地址,故称为相对地址、程序地址、或称虚拟地址。)在操作系统中一般通过快表来实现虚拟地址到物理地址的转换,同时判断这个虚拟地址是否有效。

有关术语解释物理地址 (physical address):放在寻址总线上的地址。放在寻址总线上,如果是读,电路根据这个地址每位的值就将相应地址的物理内存中的数据放到数据总线中传输。如果是写,电路根据这个地址每位的值就在相应地址的物理内存中放入数据总线上的内容。物理内存是以字节(8位)为单位编址的。

地址空间

我们把程序中有符号名组成的空间称为地址空间。源程序经过汇编或编译后再经过链接编辑程序加工形成的程序的装配模块,及转换为相对地址编址的模块,它是以0为基址顺序进行编址的。相对地址也称为逻辑地址或虚拟地址,把程序中由相对地址组成的空间叫做逻辑地址空间。相对地址空间通过地址再定位机构转换到绝对地址空间,绝对地址空间也叫物理地址空间。1

存储空间

简单来说,逻辑地址空间(简称地址空间)是逻辑地址的集合,物理地址空间(简称存储空间)是物理地址的集合。

块表概述又可以称之为页表缓存、转址旁路缓存,为CPU的一种缓存,由内存管理单元用于改进虚拟地址到物理地址的转译速度。目前所有的桌面型及服务器型处理器(如 x86)皆使用TLB。TLB具有固定数目的空间槽,用于存放将虚拟地址映射至物理地址的标签页表条目。为典型的内容可寻址内存(content-addressable memory,首字母缩略字:CAM)。其搜索关键字为虚拟内存地址,其搜索结果为物理地址。如果请求的虚拟地址在TLB中存在,CAM 将给出一个非常快速的匹配结果,之后就可以使用得到的物理地址访问内存。如果请求的虚拟地址不在 TLB 中,就会使用标签页表进行虚实地址转换,而标签页表的访问速度比TLB慢很多。有些系统允许标签页表被交换到次级存储器,那么虚实地址转换可能要花非常长的时间。

TLB 用于缓存一部分标签页表条目。TLB可介于 CPU 和 CPU缓存之间,或在 CPU 缓存和主存之间,这取决于缓存使用的是物理寻址或是虚拟寻址。如果缓存是虚拟定址,定址请求将会直接从 CPU 发送给缓存,然后从缓存访问所需的 TLB 条目。如果缓存使用物理定址,CPU 会先对每一个内存操作进行 TLB 查寻,并且将获取的物理地址发送给缓存。两种方法各有优缺点。

采用物理寻址的缓存的一种常见优化,是并行的进行 TLB 查寻和缓存的访问。所有虚拟地址的较低比特(例如,在虚拟内存系统中具有 4KB 标签页时,虚拟地址中较低的那 12 比特)代表的是所请求的地址在分页内部的地址偏移量(页内地址),且这些比特不会在虚拟地址转换到物理地址的过程中发生改变。访问CPU缓存的过程包含两步:使用一条索引去寻找CPU缓存的数据存储区中的相应条目,然后比较找到的CPU缓存条目的相应标记。如果缓存是用虚实地址转译过程中不变的页内地址来索引组织起来的,则可并行地执行TLB上虚实地址的较高比特(即分页的页间地址/页号)的转换与CPU缓存的“索引”操作。然后,从 TLB 获得的的物理地址的页号会发送给CPU缓存。CPU缓存会对页号标记进行比较,以决定此次访问是寻中或是缺失。它也有可能并行的进行 TLB 查寻和CPU缓存访问,即使CPU缓存必须使用某些可能会在地址转译后发生改变的比特;参阅缓存条目的地址转译一节,以获取关于虚拟定址下缓存和 TLB 的进一步细节。

处理方案两种在现代体系结构中常用的解决 TLB 不命中的方案:

硬件式 TLB 管理,CPU 自行遍历标签页表,查看是否存在包含指定的虚拟地址的有效标签页表条目。如果存在这样的分页表条目,就把此分页表条目存入 TLB ,并重新执行 TLB 访问,而此次访问肯定会寻中,程序可正常运行。如果 CPU 在标签页表中不能找到包含指定的虚拟地址有效条目,就会发生标签页错误异常,操作系统必须处理这个异常。处理标签页错误通常是把被请求的数据载入物理内存中,并在标签页表中创建将出错的虚拟地址映射到正确的物理地址的相应条目,并重新引导程序。2

软件管理式 TLB,TLB 不命中时会产生“TLB 失误”异常,且操作系统遍历标签页表,以软件方式进行虚实地址转译。然后操作系统将分页表中响应的条目加载 TLB 中,然后从引起 TLB 失误的指令处重新引导程序。如同硬件式 TLB 管理,如果操作系统在标签页表中不能找到有效的虚实地址转译条目,就会发生标签页错误, 操作系统 必须进行相应的处理。

64 位 Windows 内核虚拟地址空间布局X64 CPU 仅支持 64 位虚拟地址中的 48 位,这 48 位虚拟地址被运行在该 CPU 上的软件使用。 对于用户模式地址,64 位虚拟地址中的高 16 位总是被设置为 0x0;对于内核模式地址,总是设置为 0xF。

这有效地将 X64 地址空间分开成2部分——用户模式地址的范围:0x0000000000000000~0x0000FFFFFFFFFFFF;

内核模式地址的范围:

0xFFFF000000000000~0xFFFFFFFFFFFFFFFF。

此内核虚拟地址范围总计为 256 TB,用于 Windows 上可访问的全部内核虚拟地址空间。然后,Windows 静态划分此空间成多个固定大小的虚拟地址范围(VA),每个范围被赋予特定用途。每个范围的起始和结束地址如下表所示:

因此,为了简化处理器芯片架构以及避免非必要的开销——尤其是地址翻译方面(后面会讨论)—— 当前 AMD 和 Intel 的 x64 处理器仅实现了 16 EB 虚拟地址空间中的 256 TB。换言之,一个 64 位的虚拟地址中,仅有低 48 位被实现(使用)。然而,虚拟地址仍旧是 64 位宽,在寄存器中,或存储在内存中,它们都占用 8 字节。虚拟地址中的高 16 位(比特位 48~63)需要被设置成与最高的“实现位”(也就是比特位 47)相同的值,这是通过一种类似于二进制补码运算的符号扩展来完成的。符合这一运算规则的地址被称为“规范”(canonical)地址。

根据这些规则,正如预期的那样,地址空间的下半部分从 0x0000000000000000 开始,但是结束于 0x00007FFFFFFFFFFF。地址空间的上半部分从 0xFFFF800000000000 开始,结束于 0xFFFFFFFFFFFFFFFF。每个“规范的”部分为 128 TB。随着更新的处理器实现/使用更多的地址位,内存中的下半部分将会向上扩展,直到 0x7FFFFFFFFFFFFFFF;而内存中的上半部分则会向下扩展,直到 0x8000000000000000 (与当前的 32 位用户—内核内存空间分割法类似,只是又多出了 32 位)。3