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

在现代x86系统中,如何在保护模式内存寻址中使用段寄存器?,x86,operating-system,memory-segmentation,X86,Operating System,Memory Segmentation,我了解分段是如何工作的,分页是现代操作系统中内存访问的首选方式。但我不确定段寄存器未使用的方式: 它们只是显示为未使用,因为它们通常有基数0和限制0xFFFFFF。请注意,在这种情况下,它们仍然涉及物理地址计算,但它们是透明的,并提供了一个平面内存模型 它们一点也没有动过 也许是它们的有趣组合。从高级别(如果可以称之为高级别)的角度来看,大多数段的配置基数为0,限制为0xFFFFFF(fs和gs可用于特殊目的) 但是,将段配置为非零基可能会影响性能。例如,在AMD K8和K10上,将代码段配置为

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

  • 它们只是显示为未使用,因为它们通常有基数0和限制0xFFFFFF。请注意,在这种情况下,它们仍然涉及物理地址计算,但它们是透明的,并提供了一个平面内存模型
  • 它们一点也没有动过

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

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

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

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


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

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

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

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

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


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

    您的第一点是正确的。我们无法在保护模式下禁用分段,因此我们将其配置为不妨碍。在长模式下,它是“剥离的”,例如,基址和限制不被检查。段寄存器是一种黑客行为,允许16位处理器寻址超过64KB的内存。在32位或64位处理器上,这不再是必需的,4 PB对每个人都足够了。段寄存器就像人类的附录:它们没有任何用途。你的第一点是正确的。我们无法在保护模式下禁用分段,因此我们将其配置为不妨碍。在长模式下,它是“剥离的”,例如,基址和限制不被检查。段寄存器是一种黑客行为,允许16位处理器寻址超过64KB的内存。这在32位或64位处理器上不再是必需的,4 PB对每个人都足够了。段寄存器就像人类的附录:它们没有任何用途。英特尔的优化手册说Atom和Silvermont对于非零段基有额外的延迟(Atom对某些段前缀有额外的惩罚,比如ES=1/9周期吞吐量,但DS要便宜得多)。我没有发现任何关于Haswell的信息。我几乎可以肯定Haswell在32位模式下的速度与base=0一样快,否则人们会对64位模式下更低的负载使用延迟大为不满。(这可能是一个非常简单的硬件优化,值得一试,因为绝大多数访问都是base=0。)英特尔的优化手册说,Atom和Silvermont对于非零段基有额外的延迟(Atom对某些段前缀有额外的惩罚,比如ES=1/9周期吞吐量,但DS要便宜得多)。我没有找到任何关于Haswell的信息。我几乎可以肯定Haswell在32位模式下的速度与base=0一样快,否则在64位模式下的负载使用延迟会降低很多。(这可能是一个非常简单的硬件优化,值得做,因为绝大多数访问都是base=0。)
    .loop:
        mov rax, [rsp+rax]
        add ecx, 1
        jnz .loop
    
    .loop:
        mov rax, [gs:rax]
        add ecx, 1
        jnz .loop