【问题标题】:Why in x86-64 the virtual address are 4 bits shorter than physical (48 bits vs. 52 long)?为什么在 x86-64 中虚拟地址比物理地址短 4 位(48 位与 52 位长)?
【发布时间】:2018-03-12 13:24:43
【问题描述】:

在“低级编程:英特尔® 64 架构上的 C、汇编和程序执行”一书中,我读到:

每个虚拟 64 位地址(例如,我们在程序中使用的地址) 由几个字段组成。地址本身实际上只有 48 位 宽的;它被符号扩展为 64 位规范地址。它的 特点是它的左17位相等。如果条件是 不满意,地址在使用时立即被拒绝。然后 48位虚拟地址转化为52位物理地址 借助特殊表格的地址。

为什么虚拟地址和物理地址相差4位?

【问题讨论】:

  • 反问:为什么虚拟地址和物理地址要一样大? 1980 年代使用超过 48k 内存的 8 位计算机也使用“内存银行”,这或多或少意味着物理地址位多于虚拟地址位。
  • @MartinRosenau 很抱歉,您认为我的问题暗示 我认为虚拟地址和物理地址应该具有相同的大小。我的目的只是想问为什么在那个特殊情况下会有所不同。我发现您在评论中写的类似内容,但与“现代 PC”和 64 位寻址有关。
  • 有趣的事实:如果你想使用高 16 位标记指针,你可以在使用重做符号扩展之前shl rax,16 / sar rax,16。 (或者更好的是,让您的程序仅在规范范围的低半部分分配标记指针,因此您可以使用 and 或 BMI2 andn 使地址规范。)或者更好的是,仅在 4G 的低端分配虚拟地址空间,因此您可以使用地址大小 (0x67) 前缀来忽略高垃圾,或者在操作指针时使用 32 位操作数大小以免费对其进行零扩展。
  • 我猜如果/当硬件支持更广泛的虚拟地址时,可能会有一个 mmap(MAP_48BIT) 标志等同于当前的 mmap(MAP_32BIT) 所以程序想要使用高 16 位为自己的目的可以继续这样做。仅使用高字节可能会更安全,因为将虚拟扩展到物理之外的可能性较小,即使内存映射的非易失性存储成为一种东西。 (例如,DIMM 上的速度比闪存快。)

标签: assembly x86-64 memory-address virtual-memory mmu


【解决方案1】:

我相信你说的是 x86-64,我的回答是基于那个架构的。


在 64 位模式下运行时,CPU 使用改进的功能将虚拟地址转换为物理地址,称为 PAE - Physical address extension
最初发明是为了打破 4GiB 限制,同时仍使用 32 位指针,此功能涉及使用 4 级表。
每个表都给出了一个指向下一个表的指针,最右边的表给出了物理地址的高位。想了解一下来自AMD64 Architecture Programming Manual的这张图片:

所有这些表背后的基本原理是稀疏:将虚拟地址转换为物理地址的元数据非常庞大 - 如果我们只使用 4KiB 页面,我们需要 264 - 12 = 252 个条目来覆盖整个 64 位地址空间。
表允许使用稀疏方法,只有必要的条目才会填充到内存中。

这种设计体现在如何划分虚拟地址(因此间接地体现在层数上),每个层的表只使用 9 位运行来索引。
从包含的第 12 位开始,这给出:1 级 -> 12-20,2 级 -> 21-29,3 级 -> 30-38,4 级 -> 39-47。

这解释了当前仅 48 位虚拟地址空间的实现限制。
请注意,在使用逻辑地址的指令级,我们完全支持 64 位地址。
分段级别也提供全面支持,即将逻辑地址转换为线性地址的部分。
所以限制来自PAE。

我的个人意见是,AMD 急于成为第一个推出支持 64 位的 x86 CPU 并重用 PAE 的公司,将其修补为新的间接级别以转换为 48 位。
请注意,Intel 和 AMD 都允许未来的实现使用 64 位作为虚拟地址(可能有更多表)。

但是,两家公司都为物理地址设置了 52 位的硬限制。 为什么?

仍然可以在分页的工作原理中找到答案。
在 32 位模式下,每个表中的每个条目都是 32 位宽;低位用作标志(因为对齐要求使它们对翻译过程无用),但高位全部用于翻译,提供 32/32 虚拟/物理翻译。
需要强调的是,所有 32 位都已使用,而一些低位并未用作标志,英特尔将它们标记为“已忽略”或“可用”,这意味着操作系统可以免费使用它们。

当英特尔引入 PAE 时,他们需要多 4 位(当时 PAE 是 36 位),合乎逻辑的做法是将每个条目的大小加倍,因为这样可以创建比例如,一个 40 位的表条目。
这为英特尔提供了很多空闲空间,他们将其标记为保留(这可以在旧版本的英特尔 SDM 手册中更好地观察到,like this one)。

随着时间的推移,条目中需要新的属性,最著名的是XD/NX bit
保护键也是一个相对较新的功能,它在条目中占用空间。 这表明当前的 ISA 无法再进行完整的 64/64 位虚拟/物理转换。

作为视觉参考,这里是 64 位 PAE 表条目的格式:

它表明 64 位物理地址是不可能的(对于大页面,仍然有办法解决这个问题,但考虑到位的布局似乎不太可能)但没有解释为什么 AMD 将限制设置为 52位。

嗯,很难说。
当然,物理地址空间的大小有一些与之相关的硬件成本:更多的引脚(尽管使用集成内存控制器,由于 DDR 规范多路复用大量信号,这得到了缓解)和更多空间在缓存/TLB 中。
在这个question(类似但不够重复)中,一个答案城市维基百科又据称引用了 AMD,声称 AMD 的工程师在充分考虑收益和成本后将限制设置为 52 位。

我分享Hans Passant wrote more than 6 years ago 的内容:当前的分页机制不适合完整的 64 位物理寻址,这可能是英特尔和 AMD 从不打扰保留每个条目中的高位的原因。

两家公司都知道,随着该技术将接近 52 位限制,它也将与目前的形式大不相同。
到那时,他们通常会设计出一种更好的内存机制,因此他们避免过度设计现有的机制。

【讨论】:

  • 非常感谢您的回复!是惊人的!!您说:“仅使用 9 位运行来索引每个级别的表”,然后再描述虚拟地址组件。但是作者说每个表索引都使用12bits(加起来48bit)而不是9bit。我只是说以防万一有好事来自这个观察。其他位是一个符号位,其他 17 位(加起来 64 位)必须等于地址,而不是像我的书名中所说的那样被丢弃。作者将该架构描述为“Intel 64架构:也称为x86_64和AMD64”
  • @Margaret:Hans 只是说 4k 页面太小了。如果用于非易失性存储的巨大内存空间开始成为现实,我怀疑 TLB 将开始为 1G 大页面获取更多条目(当前 = Skylake 中完全关联的 4x 1G 条目),并且操作系统将允许用户空间映射非易失性存储有 1G 的大页面。我猜大多数数据库进程都需要一个或两个巨大的连续映射,而 2 级页表(1G 巨页而不是 PDPTE 的有效深度)就可以了,对吧?据我了解,当映射稀疏时,拥有更多级别通常会有所帮助。
  • 即使是 2MB 的页面也不可怕;汉斯甚至建议4M可能还可以。 (这就是 x86-32 的巨页大小。)顺便说一句,只有像数据库这样的高性能软件才会想要将非易失性存储 DIMM 映射到自己的虚拟地址空间中,以实现相当于直接 IO 的效果。其他一切都将通过文件系统。或者,如果它足够快(或 DRAM 有限/不存在),操作系统可以通过将非易失性存储直接映射到 1G/2M/4k 页面来满足mmap(PROT_READ|PROT_EXEC) 请求。将您的映射限制为 2M 的 2M 对齐倍数将是一个完美的胜利。
  • @PeterCordes,是的,确实 4KiB 是有问题的。巨大的页面绝对是唯一的出路。当我们达到 2^52 的限制时,很难说未来会怎样,像 GiB 这样的大小甚至可能被认为很小。就我个人而言,我相信具有可直接访问 TLB 的软件遍历表将是一种更好的方法(就像某些 MIPS 实现 IIRC 一样)
  • @MargaretBloom 我的错,我错过了解释。正如你所说的是9位:4 * 9位(每个索引)+ 12位(偏移量)= 48位。
猜你喜欢
  • 2011-10-06
  • 2021-01-06
  • 2016-10-29
  • 1970-01-01
  • 2015-07-09
  • 2013-05-05
  • 1970-01-01
  • 2015-01-13
  • 1970-01-01
相关资源
最近更新 更多