【问题标题】:How are segment registers unused in protected mode memory addressing in modern x86 systems?在现代 x86 系统中,如何在保护模式内存寻址中未使用段寄存器?
【发布时间】:2018-02-09 00:03:07
【问题描述】:

我了解分段的工作原理,并且分页是现代操作系统中内存访问的首选方式。但我不确定段寄存器未使用的方式:

  1. 它们只是出现未使用,因为它们通常具有基数 0 和限制 0xFFFFFFFF。请注意,在这种情况下,它们仍然参与物理地址计算,但它们是透明的并提供平面内存模型。
  2. 它们完全没有受到影响。

【问题讨论】:

  • 您的第一点是正确的。我们无法在保护模式下禁用分段,因此我们将其配置为不妨碍。在长模式下,它被“剥离”,例如不检查 base 和 limit。
  • 段寄存器是一种允许 16 位处理器处理超过 64KB 内存的黑客行为。这在 32 位或 64 位处理器上不再需要了,4 PB 对每个人来说都足够了。
  • 段寄存器就像人类的附录:它们没有任何作用。

标签: x86 operating-system memory-segmentation


【解决方案1】:

也许是它们的有趣组合。从高级别(如果可以称为高级别)的角度来看,大多数段都配置有 0 基数和 0xFFFFFFFF 限制(fsgs 可能用于特殊目的)。

但是配置一个非零基数的段可能会产生性能影响。例如,在 AMD K8 和 K10 上,将代码段配置为具有非零基数会使分支错误预测的延迟增加两个周期,如果涉及具有非零基数的段,则通用地址的计算周期会更长.这可能意味着处理器对基数为零的段有一个特殊的快速路径,因此基数根本不参与地址的计算,而不是加零(这仍然需要时间)。

我找不到任何其他 µarch 上存在此效果的参考,但它可能没有被充分探索,因为它是一种相对罕见的效果,尤其是在性能敏感的代码中。在快速测试中,Haswell 上似乎存在类似的效果,使用以下代码(跳过一些琐碎的设置):

.loop:
    mov rax, [rsp+rax]
    add ecx, 1
    jnz .loop

每次迭代运行两个周期(5 个周期/迭代)比此代码(7 个周期/迭代)快:

.loop:
    mov rax, [gs:rax]
    add ecx, 1
    jnz .loop

这可能意味着更多的英特尔 µarch 也会受到影响,尽管这可能是不准确的,因为第一个代码根本不涉及任何段(因为它是 64 位代码),也许 才是最重要的.

【讨论】:

  • 英特尔的优化手册说,Atom 和 Silvermont 对非零段基础有额外的延迟(并且 Atom 对某些段前缀有额外的惩罚,比如 ES = 1 每 9 个周期的吞吐量,但 DS 便宜得多) .我没有找到任何关于 Haswell 的信息。我几乎可以肯定 Haswell 在 base=0 的 32 位模式下会一样快,否则人们会在 64 位模式下降低负载使用延迟。 (这可能是一个非常简单的硬件优化,值得一试,因为绝大多数访问都使用 base=0。)
猜你喜欢
  • 1970-01-01
  • 2017-01-03
  • 2011-11-07
  • 1970-01-01
  • 2013-11-22
  • 2012-05-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多