【问题标题】:Is this intel pipelining instruction?这是英特尔流水线指令吗?
【发布时间】:2019-06-13 11:20:58
【问题描述】:

据我所知,intel 8086 pipelining 是技术
即在执行当前指令时获取下一条指令

This 文章说流水线的优势之一
消除欧盟的等待时间并加快处理速度

我认为,像lea 0x7(%eax), %ecx 这样的指令可以分成几条指令,
喜欢add $0x7, %eax; lea %eax, %ecx

我的想法)
所以,根据定义,
我认为上面的例子符合intel 8086 pipelining
的定义 因为它在一个时隙执行几条指令并且
所以像这样的操作加快了处理速度

问题)
我很好奇下面的说明可以是流水线的例子。

main:
 mov $0x2, %eax
 mov $0x3, %esi
 lea (%eax), %ecx           # result: 2. Pipeling?
 lea 0x7(%eax), %ecx        # result: 9. Pipeling?
 lea 0x7(%eax,%esi,), %ecx  # result: 12. Pipeling?
 lea 0x7(,%esi,4), %ecx     # result: 19. Pipeling?
 lea 0x7(%eax,%esi,4), %ecx # result: 21. Pipeling?

【问题讨论】:

  • 流水线是CPU的一个特性,它不适用于单条指令。
  • 并不特定于 intel 或 x86,它被广泛使用。
  • 虽然我认为 8086 没有使用它,但它有一个小的预取缓冲区......

标签: assembly intel x86-16 disassembly pipelining


【解决方案1】:

最初的计算机不是流水线的。他们获取一条指令,执行指令所需的所有周期并传递给下一条指令。平均而言,一条指令需要 5-6 个周期。 这种行为适用于 80 年代中期之前的所有计算机,包括 8086(在 78 中引入)。

七十年代后期,人们发现流水线是一种提高效率的有效方式。第一个商用芯片是 IBM 801,但流水线的成功是在八十年代中期与 Sun Sparc、Berkeley Risc 和 MIPS 合作的。

想法是将所有指令拆分为相似的阶段,并将这些阶段与独立的硬件资源相关联,这样您就可以开始一条新指令,而无需等待前一条指令完成,从而允许开始一条新指令每个周期的指令。为了处理指令交互(危险),每约 1.5 个周期增加 1 条指令,但与上一代相比增益巨大(X3 性能)。

问题在于流水线需要特定的指令集,基于简单的数据移动(称为 RISC 指令集)。新计算机基于此方案,但未采用旧处理器指令集(包括 x86)。

为了从流水线优势中获益,同时保持向上兼容性,英特尔决定采用基于两部分的微架构:第一部分获取 x86 指令并将其转换为可流水线指令(称为 μOps),第二部分是流水线执行这些μOps。这是在 Pentium Pro(1995 年推出)中首次引入的,并且出现在任何后续版本中。

你提供的代码

lea 0x7(%eax), %ecx

翻译成

添加 $0x7, %eax;
lea %eax, %ecx

是 μOps 转换的示例。转换在将具有内存中操作数的 ALU 操作转换为执行单个任务(内存传输或 ALU 操作)的更简单操作时特别有用。

目前所有的计算机都是流水线的(除了一些简单的微控制器或一些嵌入在 FPGA 中的处理器)。

无论您给出的指令序列都将在管道中执行,当然包括您问题中的指令。唯一的限制是,根据指令交互,可能存在可能意味着流水线减速(停顿)的危险。

我认为上面的例子符合 intel 8086 流水线的定义

流水线是微架构的特征,而不是指令集的特征。因此,微架构 8086 不是流水线,而是其指令集(称为 x86 或 IA32)的后续架构实现。

因为它在一个时隙执行多条指令

您实际上是对的,可以在一个时隙启动多条指令,但这是流水线之上的另一种技术,允许在指令级别并行执行并称为超标量。

【讨论】:

  • 原始 8086 流水线指令预取,带有 6 字节缓冲区。与流水线解码/执行/等相比,这确实很容易实现,但它仍然是一些甚至更早的 CPU 所没有的流水线。
  • PPro(第一代 P6 系列)率先将 x86 指令解码为类似 RISC 的微指令。 486 和 Pentium 只是在可能的情况下对 x86 指令进行流水线化处理,从而更有效地使用更多但更简单的 x86 指令(例如避免内存目标add [mem], reg,因为即使它可以在任一管道中配对,它也需要 3 个周期才能在另一个管道之前(一对) 指令可以开始执行。) 在 P5 Pentium 上,避免 push/pop 有时也很好。但在 P6 添加堆栈引擎以摆脱堆栈指针更新 uops 之前,这对 P6 来说主要是件好事,而 P5 可以配对 push/pop。
  • 将 LEA 拆分为 ADD 和 LEA(我猜实际上是 MOV?)并不是一个很好的例子。就是这样的想法,但解码甚至没有意义(它修改了原始的 EAX),并且 shift+add 并不难,因此 LEA 始终是所有 CPU 上的单个 uop,将复杂的指令解码为多个 uop。一个更好的例子是内存目标添加,即加载+添加+存储。
  • 是的,流水线与非流水线是实施决策。但是一些 ISA 明确公开了一些流水线。例如MIPS 和其他一些 RISC 上的分支延迟槽,尤其是早期的 MIPS 加载延迟槽(在下一条指令中使用加载的结果会产生不可预测的结果;第一代 MIPS CPU 硬件不会为依赖关系互锁,因此ISA 未定义)。此外,Mill 延迟加载仅在一些其他指令之后才写入其目标寄存器。 (因此您可以将 ILP 暴露给有序管道。)
  • 查看 Agner Fog 的 microarch pdf (agner.org/optimize) 了解 P5 Pentium 与 P6 和有序 Atom 中的管道的详细信息。 (与有序 P5 不同,有序 Atom(不是 Silvermont)确实解码为 uops。)
猜你喜欢
  • 2023-03-06
  • 2020-05-12
  • 2012-11-13
  • 1970-01-01
  • 2013-09-08
  • 2020-08-23
  • 2019-08-02
  • 1970-01-01
  • 2015-09-09
相关资源
最近更新 更多