段寄存器如何在现代 x86 系统的保护模式内存寻址中未使用?

How are segment registers unused in protected mode memory addressing in modern x86 systems?

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

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

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

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

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

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

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

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

可能这意味着更多的 Intel µarchs 也会受到影响,尽管这可能是不准确的,因为第一个代码中根本没有涉及任何段(因为它是 64 位代码)并且可能 that 才是最重要的。