【发布时间】:2020-01-23 01:03:19
【问题描述】:
CPU 如何检查流水线阶段是否繁忙,以便它可以阻止所有先前的阶段?也就是说,在一个三阶段流水线示例中,如果阶段 2 占用多个时钟周期并停止流水线,那么 CPU 怎么知道不向前移动阶段 1?
【问题讨论】:
标签: x86 x86-64 cpu intel cpu-architecture
CPU 如何检查流水线阶段是否繁忙,以便它可以阻止所有先前的阶段?也就是说,在一个三阶段流水线示例中,如果阶段 2 占用多个时钟周期并停止流水线,那么 CPU 怎么知道不向前移动阶段 1?
【问题讨论】:
标签: x86 x86-64 cpu intel cpu-architecture
首先,x86-64 作为标签没有什么意义。有真正的 ARM CPU 具有 3 级管道(例如 Cortex-M),但从来没有 x86-64 CPU 这么短。 x86 解码对于这么短的管道来说太贵了,而且“x86 税”对于简单的 CPU 来说占用了太多的空间/性能。
很明显,任何给定的阶段都可以检测到何时需要启动停顿。例如。内存访问阶段可以检测缓存未命中加载或存储缓冲区已满(这需要在没有任何内存级别并行性的简单 CPU 上停止管道,这与真正的现代 x86 不同,后者可以推测地命中未命中和未命中。错过)。我认为您只是在问这些信息是如何向后传播的。
在可能停滞1的管道中,每个阶段都必须为下一个阶段无法准备好接受新内容的可能性做好准备。您只需要发出前一阶段的信号,而不是之前的所有阶段。管道中的早期气泡可能会关闭。
明显的实现是从每个阶段到前一个阶段的信号线。
如果一个阶段还没有准备好接受新工作,它就会发出这个信号。在通常将数据从一个阶段传播到另一个阶段的时钟沿上,如果设置了该信号,则前一个阶段会保留其数据。
如果管道已满,最后阶段的停顿将导致管道向后波动。 (先前为空的流水线阶段可以停止传播:即使下一个阶段不能从它们那里获取任何工作,它们仍然可以在这个周期接受新工作。)这种反向传播可以早于时钟沿开始,例如后期检测到它需要停止。
在实践中,在阶段之间缓冲数据的锁存器可能会吸收一些这种波纹延迟并将其从关键路径中移除。就像也许数据总是可以在阶段之间的边界处被锁存器缓冲,但是如果该信号被提高,那么锁存器会一直保持到稍后?
IDK 您想深入了解数字逻辑/门设计。高层次的画面只是每个阶段都可以向前一个阶段发出信号,表明它还没有准备好接受这个周期的新工作。而且这个信号必须以某种方式向后传播。
脚注 1:并非所有管道都能够停止。例如全流水线整数乘法执行单元不需要流量控制。无论如何,它总是可以在每个周期接受一个新的输入。
但是是的,一个完整的 CPU 管道通常至少必须能够停止内存。
【讨论】: