Java并发编程-Amdahl 定律

80 阅读1分钟

在阅读《Java 并发编程实战》的时候,看到一个概念“Amdahl 定律”,学习整理一波。

在使用多线程来解决问题时,我们希望可用资源越多越好,这样通过多线程来充分利用这些计算资源,来提升解决问题的速度。在实际操作中,我们需要能够在方案设计阶段就预估和评价出“增加资源后提升的效果如何”,该怎么预估评价能达到的效果上限?

这就是 Amdahl 定律的作用,它描述的是:在增加计算资源的情况下,程序在理论上能够实现的最高加速比

大多数并发程序要解决的问题,都是由一系列“并行工作”和“串行工作”组成的,Amdahl 定律指出:使用多处理器能够提升的加速比,受限于程序中“串行工作占比”。

假设在并行优化前程序解决问题的耗时为T0T_0,在使用并行优化后程序解决问题的耗时为T1T_1,前者与后者的比值为加速比SS。程序中能够并行执行的部分比重为aa,串行执行的部分比重为F=1aF=1-a。如果有NN个处理器在并行执行,那么最高能得到的加速比为:

S11a+aN=1F+(1F)NS \le \frac{1}{1-a+\frac{a}{N}} = \frac{1}{F+\frac{(1-F)}{N}}

不同比例的aa值下,加速比与 CPU 个数的关系曲线如下图所示:

从公式和曲线可以看出,哪怕NN趋向于无穷大,最大的加速比才能接近于1F\frac{1}{F},因此当程序需要做性能提升时,不断增加 CPU 带来的收益是有限的。如果程序中有 50% 的计算需要串行执行,不管有多少个线程和CPU,最高的加速比只能是 2。

FF值为 0 的时候“加速比”等于“CPU 个数”,这种情况下才能百分百利用资源,所以 Amdahl 从另一方面描述了资源的利用率(加速比 / CPU 个数 N)。

在并发编程时,如果要想让提升的效果更加明显可以有以下三个途径:

1、优化或分离串行部分和并行部分

2、提升并行部分的比重

3、增加 CPU 个数(后期效果有限)

这篇文章给出了公式推导:www.inlighting.org/archives/am…

这篇文章给出了一个图例,方便理解公式:icefrozen.github.io/article/arc…