# 4.4.3 流水线的局限性

图 4-33 的例子给出了一个理想的流水线化的系统,在这个系统中,我们可以将计算分成三个相互独立的阶段,每个阶段需要的时间是原来逻辑需要时间的三分之一。不幸的是,会出现其他一些因素,降低流水线的效率。

# 1. 不一致的划分

图 4-36 展示的系统中和前面一样,我们将计算划分为了三个阶段,但是通过这些阶段的延迟从 50ps 到 150ps 不等。通过所有阶段的延迟和仍然为 300ps。不过,运行时钟的速率是由最慢的阶段的延迟限制的。流水线图表明,每个时钟周期,阶段 A 都会空闲(用白色方框表示)100ps,而阶段 C 会空闲 50ps。只有阶段 B 会一直处于活动状态。我们必须将时钟周期设为 150 + 20 = 170ps,得到吞吐量为 5.88 GIPS。另外,由于时钟周期减慢了,延迟也增加到了 510ps。

图 4-36 由不一致的阶段延迟造成的流水线技术的局限性

图 4-36 由不一致的阶段延迟造成的流水线技术的局限性。系统的吞吐量受最慢阶段的速度所限制

对硬件设计者来说,将系统计算设计划分成一组具有相同延迟的阶段是一个严峻的挑战。通常,处理器中的某些硬件单元,如 ALU 和内存,是不能被划分成多个延迟较小的单元的。这就使得创建一组平衡的阶段非常困难。在设计流水线化的 Y86-64 处理器中,我们不会过于关注这一层次的细节,但是理解时序优化在实际系统设计中的重要性还是非常重要的。

练习题 4.28 假设我们分析图 4-32 中的组合逻辑,认为它可以分成 6 个块,依次命名为 A~F,延迟分别为 80、30、60、50、70 和 10ps,如下图所示:

输入 → A → B → C → D → E → F → 寄存器

组件 A B C D E F 寄存器
延迟(ps) 80 30 60 50 70 10 20

时钟 → 寄存器

在这些块之间插入流水线寄存器,就得到这一设计的流水线化的版本。根据在哪里插入流水线寄存器,会出现不同的流水线深度(有多少个阶段)和最大吞吐量的组合。假设每个流水线寄存器的延迟为 20ps。

A. 只插入一个寄存器,得到一个两阶段的流水线。要使吞吐量最大化,该在哪里插入寄存器呢?吞吐量和延迟是多少?

B. 要使一个三阶段的流水线的吞吐量最大化,该将两个寄存器插在哪里呢?吞吐量和延迟是多少?

C. 要使一个四阶段的流水线的吞吐量最大化,该将三个寄存器插在哪里呢?吞吐量和延迟是多少?

D. 要得到一个吞吐量最大的设计,至少要有几个阶段?描述这个设计及其吞吐量和延迟。

# 2. 流水线过深,收益反而下降

图 4-37 说明了流水线技术的另一个局限性。在这个例子中,我们把计算分成了 6 个阶段,每个阶段需要 50ps。在每对阶段之间插入流水线寄存器就得到了一个六阶段流水线。这个系统的最小时钟周期为 50 + 20 = 70ps,吞吐量为 14.29 GIPS。因此,通过将流水线的阶段数加倍,我们将性能提高了 14.29/8.33 = 1.71。虽然我们将每个计算时钟的时间缩短了两倍,但是由于通过流水线寄存器的延迟,吞吐量并没有加倍。这个延迟成了流水线吞吐量的一个制约因素。在我们的新设计中,这个延迟占到了整个时钟周期的 28.6%。

图 4-37 由开销造成的流水线技术的局限性

图 4-37 由开销造成的流水线技术的局限性。在组合逻辑被分成较小的块时,由寄存器更新引起的延迟就成为了一个限制因素

为了提高时钟频率,现代处理器采用了很深的(15 或更多的阶段)流水线。处理器架构师将指令的执行划分成很多非常简单的步骤,这样一来每个阶段的延迟就很小。电路设计者小心地设计流水线寄存器,使其延迟尽可能地小。芯片设计者也必须小心地设计时钟传播网络,以保证时钟在整个芯片上同时改变。所有这些都是设计高速微处理器面临的挑战。

练习题 4.29 让我们来看看图 4-32 中的系统,假设将它划分成任意数量的流水线阶段 k,每个阶段有相同的延迟 300/k,每个流水线寄存器的延迟为 20ps。

A. 系统的延迟和吞吐量写成 k 的函数是什么?

B. 吞吐量的上限等于多少?