Assembly 为什么增加管道深度并不总是意味着增加吞吐量?

Assembly 为什么增加管道深度并不总是意味着增加吞吐量?,assembly,intel,pipelining,Assembly,Intel,Pipelining,这也许更像是一个讨论问题,但我认为stackoverflow可能是提出这个问题的合适地方。我正在研究教学流水线的概念。我被告知,一旦管道阶段的数量增加,管道的指令吞吐量就会增加,但在某些情况下,吞吐量可能不会改变。在什么情况下会发生这种情况?我认为暂停和分支可能是这个问题的答案,但我想知道我是否遗漏了一些关键的东西。我还认为,如果将流水线增加到一个系列中最长的指令执行所需的时间之外,将不会导致性能的提高。我确实认为失速和分支是最基本的问题。长管道中的失速/气泡肯定会导致吞吐量的巨大损失。当然,管

这也许更像是一个讨论问题,但我认为stackoverflow可能是提出这个问题的合适地方。我正在研究教学流水线的概念。我被告知,一旦管道阶段的数量增加,管道的指令吞吐量就会增加,但在某些情况下,吞吐量可能不会改变。在什么情况下会发生这种情况?我认为暂停和分支可能是这个问题的答案,但我想知道我是否遗漏了一些关键的东西。

我还认为,如果将流水线增加到一个系列中最长的指令执行所需的时间之外,将不会导致性能的提高。我确实认为失速和分支是最基本的问题。

长管道中的失速/气泡肯定会导致吞吐量的巨大损失。当然,管道越长,浪费的时钟周期就越多


我花了很长一段时间思考其他场景,其中较长的管道可能会导致性能损失,但这一切都会回到停滞状态。(以及执行单元和发行方案的数量,但这些与管道长度没有多大关系。)

同意。最大的问题是暂停(等待以前指令的结果)和错误的分支预测。如果您的管道有20级深,并且您暂停等待条件或操作的结果,那么您等待的时间将比管道只有5级时长。如果预测错误的分支,则必须从管道中冲出20条指令,而不是5条


我猜想您可能有一个很深的管道,其中多个阶段尝试访问相同的硬件(ALU等),这将导致性能下降,尽管希望您投入足够的额外单元来支持每个阶段。

在等待结果或缓存未命中时,整个过程可能会被其他指令暂停。流水线本身并不能保证操作是完全独立的。 下面是一个关于x86 Intel/AMD体系结构复杂性的精彩演示:


它非常详细地解释了类似的内容,并介绍了一些关于如何进一步提高吞吐量和隐藏延迟的解决方案。JustJeff提到了一个错误的顺序执行,程序员模型没有公开阴影寄存器(x86上有8个以上的寄存器),还有分支预测。

指令级并行性的回报递减。特别是,指令之间的数据依赖关系决定了可能的并行性

以先读后写(教科书中称为RAW)为例

在第一个操作数得到结果的语法中,考虑这个例子。

10: add r1, r2, r3
20: add r1, r1, r1

第10行的结果必须在第10行的计算开始时已知。数据转发缓解了这一问题,但…仅限于数据已知的程度。

谢谢您的回答。仅供参考,我想到的另一件事是,即使我们增加管道阶段,希望将原始管道阶段逻辑分解为更小的子网络,指令也可能不会通过这些更小的网络传播,因为它最简单的管道层次结构形式可以用原始阶段逻辑来解释,所以这不会影响吞吐量。这不是20条指令,而是20个周期的指令。在超标量CPU上,这可能要多得多。