【问题标题】:What is the stack engine in the Sandybridge microarchitecture?Sandybridge 微架构中的堆栈引擎是什么?
【发布时间】:2016-08-06 12:10:45
【问题描述】:

我正在阅读http://www.realworldtech.com/sandy-bridge/,但我在理解一些问题时遇到了一些问题:

专用的堆栈指针跟踪器也存在于 Sandy Bridge 中 并重命名堆栈指针,消除串行依赖和 删除一些微指令。

dedicated stack pointer tracker 实际上是什么?

对于 Sandy Bridge(和 P4),英特尔仍然使用 ROB 一词。但它 理解这一点至关重要,在这种情况下,它仅指 飞行中微指令的状态数组

实际上是什么意思?请说清楚。

【问题讨论】:

    标签: assembly x86 intel cpu-architecture


    【解决方案1】:
    1. Agner Fog's microarch doc explains 一样,堆栈引擎在管道的发布阶段(在将 uops 发布到乱序 (OoO)核心的一部分)。

      因此内核的 OoO 执行部分只需处理加载/存储部分,地址由堆栈引擎生成。当 8 位位移计数器溢出时,或者当 OoO 内核直接需要 rsp 的值时(例如,sub rsp, 8,或在 call 之后的 mov [rsp-8], eaxretpushpop 通常会导致在 Intel CPU 上插入额外的微指令。AMD CPU 显然不需要额外的同步微指令。

      请注意,Agner 的指令表显示 Pentium-M 和更高版本将 pop reg 解码为仅在加载端口上运行的单个 uop。但是 Pentium II/III 将pop eax 解码为 2 uop; 1 个 ALU 和 1 个负载,因为没有堆栈引擎来处理乱序核心之外的 ESP 调整。除了需要额外的微指令之外,一长串的 push/pop 和 call/ret 会创建对 ESP 的串行依赖,因此乱序执行必须在 mov ebp, esp 或地址可用的值之前仔细检查 ALU 微指令为mov eax, [esp+16]


    1. P6 微架构系列(PPro 到 Nehalem)将 uop 的输入值直接存储在 ROB 中。在问题/重命名时,“冷”寄存器输入从架构寄存器文件读取到 ROB(由于读取端口有限,这可能是一个瓶颈。请参阅寄存器读取停顿)。执行一个微指令后,结果会被写入 ROB 以供其他微指令读取。当 uops 退出时,架构寄存器文件会使用来自 ROB 的值进行更新。

      SnB 系列微架构(和 P4)具有物理寄存器文件,因此 ROB 存储寄存器编号(即间接级别)而不是直接存储数据。 Re-Order Buffer 对于这部分 CPU 来说仍然是一个很好的名称。

    请注意,SnB 引入了 AVX,具有 256b 个向量。与仅将它们保存在较小的 FP 寄存器文件中相比,使每个 ROB 条目足够大以存储双倍大小的向量可能是不可取的。

    SnB 简化了 uop 格式以节省功耗。不过,这确实导致了 uop 微融合能力的牺牲:解码器和 uop-cache 仍然可以使用 2 寄存器(索引)寻址模式 but they're "unlaminated" before issuing into the OOO core 来微融合内存操作数。

    【讨论】:

    • OOO core 可以扩展一下缩写吗?
    • @Gilgamesz:CPU 内核乱序。 (嗯,谷歌没有为“ooo core”提供,只为“ooo cpu”提供。“ooo 核心”是 uop 在“发布/重命名”和“退休”阶段之间的生命周期的一部分,其中 uops 处于ROB。有关图表,请参见realworldtech.com/haswell-cpu(以及他早期的 SnB 文章)。
    • 当我开始阅读答案的第一行时,我就知道它何时由 Peter Cordes 撰写,真是绝妙的洞察力。
    【解决方案2】:

    堆栈机器有点像另一个执行/内存端口。正如雾所说:

    PUSH、POP、CALL 和 RET 指令对堆栈指针的修改是由一个特殊的堆栈引擎完成的。 ...这将管道从修改堆栈指针的μops的负担中解脱出来。

    这就是 rsp+=8 / rsp-=8 算术的处理。它们由堆栈机器处理,而不会竞争执行端口资源。但还有更多。

    16 深的硬件返回地址堆栈(英特尔® 64 位和 IA-32 架构优化参考手册的第 3.4.1.4 节)是返回地址的快速影子。它出现在 Pentium M 中。它也用于回报预测。在 Fog 的 Microarchitecture 文档中搜索“返回堆栈缓冲区”,但不多。

    所以现在您有了一些不错的硬件来减少堆栈算术的执行端口争用和快速缓存返回地址值。您可以通过尝试智取堆栈机器来使堆栈机器的生活变得困难。基本上,总是匹配 call/rets 和 pushes 和 pops。那你就可以走了。

    【讨论】:

    • push 之后使用pop 无关紧要,如果您使用mov rbp, rsp[rsp+8] 用于本地,或类似推送和弹出之间的任何东西。任何显式使用堆栈指针都会强制堆栈引擎插入一个额外的 uop 以更新 OOO 核心的值。更像是:在call(应该返回ret)之后,POP 一次会比add rsp, 8 便宜,而且代码更小。
    • 您将返回地址预测器与堆栈引擎混为一谈,这比 IMO 更令人困惑。它们彼此正交;每个都可以独立存在,您可以独立观察它们的影响。真正的代码总是破坏堆栈引擎,但是使用add esp, 16而不是4条pop指令,或者使用push rbx/sub rsp, 128在保存寄存器后在函数开始附近保留堆栈空间以供稍后恢复.最小化它必须插入的额外微指令很有用,但不是很重要。但不要中断通话/转机配对!
    • @PeterCordes "but using" 我无法解析那句话。通过使用?
    • 哦,我想我漏掉了句子的结尾:但是使用 add/sub 而不是 push/pop 是值得的,因为它可以节省总 uops 以对 E/RSP 进行更大的更改,即使它导致在后端显式(非隐式)访问 E/RSP 的堆栈同步 uop。
    猜你喜欢
    • 2016-08-12
    • 2011-04-11
    • 2010-11-30
    • 2015-11-15
    • 2014-10-16
    • 2019-11-09
    • 2012-04-21
    • 2014-08-09
    • 1970-01-01
    相关资源
    最近更新 更多