吞吐率与延迟:一对欢喜冤家

做芯片设计这些年,我经常被问到同一个问题:“流水线到底能带来什么好处?”

很多人第一反应是“让系统跑得更快”。嗯,这话对了一半。更准确地说,流水线提升的是吞吐率,而不是延迟。这两个概念,我见过太多工程师把它们混为一谈。

今天我们就来掰扯清楚。

吞吐率 vs 延迟:本质区别在哪?

先看两个定义:

  • 吞吐率(Throughput):单位时间内能处理的任务数量。比如每秒能处理多少个数据包、多少条指令。
  • 延迟(Latency):单个任务从开始到结束所花的时间。比如一个数据包从输入到输出需要多少纳秒。

我习惯用一个比喻来解释:高速公路 vs 快递。

高速公路的车流量(吞吐率)很大,但每辆车从A到B的时间(延迟)可能并不短。而一条乡间小路,车流量小,但每辆车跑完全程可能更快——因为不堵车。

你看,吞吐率和延迟,不是一回事。

核心结论:流水线提升的是吞吐率,而不是延迟。实际上,流水线往往还会增加延迟。

为什么流水线能提升吞吐率?

这个问题,咱们用数字说话。

假设一个任务需要4个步骤,每个步骤耗时1个时钟周期。非流水线设计:

  • 一个任务完成需要4个周期
  • 每4个周期才能出一个结果
  • 吞吐率 = 0.25 任务/周期

流水线设计(4级流水):

  • 第一个任务需要4个周期出结果
  • 之后每个周期都能出一个结果
  • 吞吐率 = 1 任务/周期

吞吐率提升了4倍!但第一个任务的延迟,从4个周期变成了4个周期(其实没变,但后续任务延迟被隐藏了)。

说白了,流水线就是把一个大任务拆成多个小步骤,让每个步骤同时干活。你想想看,原来只有一个人在干活,现在4个人流水作业,效率当然高。

一个真实的例子:RISC-V 处理器

我在做RISC-V处理器设计时,遇到过这样一个场景。

非流水线处理器执行一条指令:

取指 → 译码 → 执行 → 访存 → 写回
每个阶段1个周期,共5个周期完成一条指令

5级流水线处理器:

周期1: 取指(指令1)
周期2: 译码(指令1) + 取指(指令2)
周期3: 执行(指令1) + 译码(指令2) + 取指(指令3)
周期4: 访存(指令1) + 执行(指令2) + 译码(指令3) + 取指(指令4)
周期5: 写回(指令1) + 访存(指令2) + 执行(指令3) + 译码(指令4) + 取指(指令5)
...

从第5个周期开始,每个周期都能完成一条指令。吞吐率提升了5倍。

个人经验:我曾经在一个项目中,把非流水线的DMA控制器改成3级流水线。结果吞吐率从200MB/s飙到了580MB/s。但延迟从5us增加到了7us。客户一开始不理解,后来我拿数据说话,他们才明白——对于批量数据传输,吞吐率才是关键。

流水线的代价:延迟增加

你可能会问:为什么流水线会增加延迟?

原因有两个:

  1. 流水线寄存器:每级之间要插入寄存器,这会带来额外的建立时间、保持时间开销。
  2. 流水线气泡:遇到数据相关、控制相关时,需要插入空操作(气泡),这会拖慢单个任务的完成时间。

举个例子:

非流水线:任务A → 任务B → 任务C
延迟 = 3个步骤 × 1周期 = 3周期

3级流水线:
周期1: 步骤1(任务A)
周期2: 步骤2(任务A) + 步骤1(任务B)
周期3: 步骤3(任务A) + 步骤2(任务B) + 步骤1(任务C)
周期4: 步骤3(任务B) + 步骤2(任务C)
周期5: 步骤3(任务C)

任务A的延迟 = 3周期(与非流水线相同)
但如果有气泡,延迟会增加到4-5周期

避坑指南:我曾经在一个视频处理芯片中,把流水线级数从5级加到8级,以为吞吐率能提升60%。结果因为数据相关性太强,气泡太多,实际吞吐率只提升了20%,延迟却增加了40%。后来我学乖了——流水线不是越深越好,要看实际的数据流模式。

什么时候该用流水线?

我总结了几条经验:

  • 任务可分解:每个步骤之间没有强依赖关系
  • 批量处理:有大量连续任务需要处理
  • 延迟不敏感:单个任务的延迟增加可以接受
  • 硬件资源充足:流水线需要额外的寄存器和控制逻辑

反过来,如果任务之间强相关、或者对延迟极其敏感(比如实时控制),那流水线可能不是好选择。

一张图看懂核心逻辑

下面这张SVG图,展示了非流水线与流水线的吞吐率对比:

非流水线 vs 流水线:吞吐率对比 非流水线 步骤1 步骤2 步骤3 步骤4 → 1个任务需4周期 流水线 任务1-步骤1 任务1-步骤2 任务2-步骤1 任务1-步骤3 任务2-步骤2 任务3-步骤1 任务1-步骤4 任务2-步骤3 任务3-步骤2 任务4-步骤1 任务2-步骤4 任务3-步骤3 任务4-步骤2 → 每周期出一个结果 非流水线吞吐率:0.25 任务/周期 | 流水线吞吐率:1 任务/周期

总结一下

吞吐率和延迟,是芯片设计中的一对基本矛盾。流水线通过空间换时间的方式,大幅提升吞吐率,但代价是延迟增加和硬件开销。

我个人习惯在设计初期先问自己三个问题:

  1. 这个模块是吞吐率敏感还是延迟敏感?
  2. 任务之间有没有数据依赖?
  3. 硬件预算够不够加流水线寄存器?

想清楚这三点,流水线设计就不会跑偏。

一句话记住:流水线让系统“多快好省”地处理大量任务,但别指望它能加速单个任务。

可可精品资料库