GPU编程实战(基于Python和CUDA)
上QQ阅读APP看书,第一时间看更新

接下来,我们介绍阿姆达尔定律。阿姆达尔定律实际上就是一个简单的数字公式,用于估计将串行程序的某些代码放到多个处理器上并行执行时可能带来的潜在速度增益。为了便于理解,我们沿用建造房子的例子来介绍该定律。

在前面的例子中,整个工期仅与房子的实际物理建造过程有关,但现在,我们把设计房子的时间也考虑进来。假设世界上只有一个人有能力设计你的房子——这个人就是你,并且设计房屋需要100小时。地球上没有人能与你的设计才华相提并论,所以这部分任务根本不可能由其他建筑师来分担——也就是说,不管你有什么样的资源,无论你能聘请多少人,设计这所房子都需要100小时。所以,如果你只聘请1个工人,建造这座房子所需要的全部时间就是200小时——你设计房子需要100小时,1个工人建造房子需要100小时。如果你聘请2个工人,则需要150小时——设计房子的时间仍然是100小时,而建造房子仅需要50小时。显然,建造房子的总时间的计算公式为100+100/N,其中N是聘请的工人数量。

现在回过头来想想,如果我们聘请1个工人,建造房子需要多长时间——它最终决定了聘请更多工人时的加速比,也就是说,这个过程变快了多少倍。如果我们聘请 1名工人,就会发现设计和建造房子所需的时间是相同的,即100小时。所以,我们可以说,设计房子的时间占比是0.5(50%),建造房子的时间占比是0.5(50%)——当然,这两个部分加起来是1,也就是100%。当增加工人时,我们希望对此进行比较——如果我们有2个工人,建造房子时间将减少一半。所以,与初始串行版本相比,这将花费原时间的0.5 + 0.5 / 2 = 0.75(75%),而0.75×200为150小时。我们可以看到,聘请更多工人的方法是行之有效的。此外,如果聘请N个工人,我们可以计算出N个工人并行施工所需时间占原时间的比例,具体计算公式为0.5 + 0.5/N

现在,让我们确定通过增加工人而获得的加速比。如果我们有2个工人,建造一所房子需要原时间的75%,那么可以用0.75的倒数来确定并行化的加速比——也就是说,加速比将是1/0.75,比只有1个工人时的速度约快1.33倍。在这种情况下,如果我们聘请N个工人,加速比将变为1/(0.5+0.5 /N)。

随着聘请更多的工人(N更大),0.5/N将接近于0,所以当并行化这个任务时,加速比是有一个上限的,即1/(0.5+0)=2。我们可以用估计的最大加速比除以原时间,来确定这个任务所需的绝对最小时间——200/2 = 100小时。

刚才用来确定并行编程中的加速比的原理叫作阿姆达尔定律。使用该定律时,只需要知道原始串行程序的执行时间中,可并行化的代码的执行时间所占比例(称为p),以及可用的处理器内核数量N


在这种情况下,无法并行化的代码的执行时间比例总是 1−p,所以我们只需要知道p

现在,我们可以用阿姆达尔定律来计算加速比(Speedup,用S表示)了,具体公式如下所示:

综上所述,阿姆达尔定律就是一个简单的公式,可以用于粗略地(非常粗略地)估计一个至少可以部分并行化的程序的潜在加速比。只要我们知道可以并行化的代码的运行时间占比(p)和运行并行化的代码的内核数量(N),就可以大致推断出是否值得为特定串行程序开发一个并行版本。