为什么你应该卖烤炉鸡蛋灌饼,而不是锅包肉?

假设你准备摆一个只有两个人的小吃摊。菜单上有两个候选:烤炉鸡蛋灌饼和锅包肉。

它们都需要五个步骤,看起来复杂度相当;但在相同的人手和设备下,鸡蛋灌饼通常能卖得更多。区别不在步骤数量,而在这些步骤能否并行,以及它们是否争抢同一个稀缺资源。

两种同为五步的流程

烤炉鸡蛋灌饼的流程是:

  1. 擀面皮;
  2. 往面皮里灌鸡蛋;
  3. 下油锅煎;
  4. 放进烤炉烤;
  5. 加小料并出餐。

两个人分工时,A 只负责不断擀面皮,B 负责其余步骤。

锅包肉的流程同样可以拆成五步:

  1. 调面糊;
  2. 裹面糊后完成第一遍炸制;
  3. 升高油温复炸;
  4. 炒热糖醋汁并挂汁;
  5. 装盒、加香菜并出餐。

在这个小摊里,A 负责调面糊和装盒,B 负责两遍炸制和炒糖醋汁。

如果只数步骤,两者都是五步;如果画出资源依赖,差别就出现了。

真正的区别是资源依赖

锅包肉的问题是:在只有一个灶台的情况下,第一遍炸、第二遍炸和炒汁都要占用同一个灶台,也都需要 B 操作。即使 B 手速再快,这三段关键流程仍然只能串行执行:上一道菜没有释放灶台,下一道菜就无法进入相同阶段。

鸡蛋灌饼则不同。油锅和烤炉是两个独立的工作站。一个饼在烤炉里烘烤时,另一个饼可以在油锅里煎;设备自行加热的间隙,B 还可以处理下一张饼。只要油锅和烤炉的容量足够,且上锅、翻面和转移等短操作可以并入相邻时间片,多个订单就可以处在不同阶段。

因此,鸡蛋灌饼天然形成了一条流水线:

订单 / 时间 1 2 3 4 5 6 7 8 9 10 11 12 13 14
订单 1 灌蛋 油锅 烤炉 出餐
订单 2 灌蛋 油锅 烤炉 出餐
订单 3 灌蛋 油锅 烤炉 出餐

每个有色块代表一个 processing stage,空白表示订单尚未进入或已经离开流水线。可以看到,三个订单都要经历 1 个时间片的灌蛋、4 个时间片的油锅、4 个时间片的烤炉和 1 个时间片的出餐,总 latency 仍然是 10 个时间片;但后一行相对前一行只向右移动 2 列,因此相邻订单可以每隔 2 个时间片进入流水线。

不要混淆 latency 和 throughput

这是流水线最容易被说错的地方。

  • Latency:完成一个订单从开始到结束需要多久;
  • Throughput:进入稳态后,单位时间能完成多少订单。

在上面的简化模型中,单个鸡蛋灌饼的 latency 仍然是 10 个时间片。流水线没有让某一张饼瞬间成熟,而是让不同订单的等待时间互相重叠,因此稳态下每 2 个时间片就能出一个饼。

如果从空流水线开始,完成 $N$ 个订单所需的时间是

\[T_{\text{pipeline}}(N)=10+2(N-1)=2N+8.\]

若完全串行执行,则需要

\[T_{\text{serial}}(N)=10N.\]

因此加速比为

\[S(N)=\frac{10N}{2N+8}.\]

当订单很多时,$S(N)$ 逐渐接近 5。这才是“效率提升 5 倍”的准确含义:它是稳态 throughput 的极限提升,而不是第一批订单从冷启动时立刻获得的提升。

例如,一个时间片是 20 秒:

  • 单个订单的 latency 是 200 秒;
  • 稳态下平均每 40 秒出一个饼;
  • 流水线填满后,6 分钟可以连续完成 9 个饼;
  • 但从空流水线开始,前 9 个饼需要 26 个时间片,也就是 8 分 40 秒。

相比之下,完全串行做 9 个饼需要 30 分钟。第一批 9 个订单的实际加速约为 $90/26\approx 3.46$ 倍;订单越多,平均效率越接近 5 倍。

卖什么,其实是在选择系统结构

这个例子不是说锅包肉天生不能流水化。如果增加灶台、炸锅或操作人员,它同样可以获得并行度。问题在于,当资源固定为“两个人、一个灶台”时,它的关键步骤集中争抢同一个 bottleneck;鸡蛋灌饼则把工作分散到了油锅、烤炉和人工操作三个工作站。

因此,比较两门生意时,不能只问“各有多少步骤”,还要问:

  1. 哪个步骤占用最稀缺的资源?
  2. 哪些等待时间可以被其他订单利用?
  3. 相邻订单最短可以间隔多久进入流程?
  4. 增加一个人或一台设备,是否真的能解除 bottleneck?

步骤数量决定不了产能。真正决定单位时间出餐量的,是依赖关系、资源冲突和最慢的流水线阶段。

所以,在这个限定条件下,你应该卖烤炉鸡蛋灌饼,而不是锅包肉。




Enjoy Reading This Article?

Here are some more articles you might like to read next: