假设我们有以下代码:
int i,j;
for(i=0; i<20; i++)
A[i] = A[i] + B[i];
for(j=0; j<8; j++){
C[j] = C[j] + D[j];
E[j] = E[j] + C[j];
}
现在让我们假设我们有14
相同的CPUS,可用于帮助我们并行计算最终结果。
执行上述代码时,使用所有14
cpus可以获得的最大加速时间是多少?假设每个操作(添加)需要1
个单位时间。
正如我所看到的,加速通常为Ts/Tp
,其中Ts
是使用1
cpu所花费的时间,而Tp
是使用所有时间所花费的时间cpus available。
在我的示例中,我们必须花费20 + 8*2 = 36
个时间单位来执行1
cpu的代码。
然后使用14
cpus,我们可以使用1
时间单位来查找14
的第一个A
值。然后使用6
cpus,我们可以使用另一个1
时间单位来查找6
的剩余A
值。
在找到A
的剩余值时,我们会使用其他8
cpus通过花费{{8
和C
来查找E
值2
1}}时间单位。
总的来说,我们会花费1 + (1 || 2) = 1 + 2 = 3
个时间单位,这意味着speedup
将是36/3 = 12
这是对的吗?我们能否以更好的方式使用cpu来实现更好的加速?此外,是否有可能以某种方式使用Amdahl定律更快地找到结果? Amdahl定律说如果x
是总代码中不能并行运行的部分那么最大值加快速度为1/(x + (1 - x)/p)
,其中p
是使用的cpus数量,因此在我的情况下,此数字将等于14
。
但是我不确定如何找到可以并行运行的代码部分。如果我决定解决以下等式:
然后x = 1/78
。但是,如何通过查看代码来找到这个x
?如果我决定更一般地查看我的问题,那么需要20
个时间单位的第一个循环可以并行运行。但是在第二个循环中,循环内的操作不能并行运行,因此在16
时间单位之外,只有8
可以并行运行。
因此,并行运行的总时间为28
。所以x = 8/36
。
所以我们从Amdahl定律得到以下结果(来自wolframalpha):
但是我按照上面解释的逻辑发现了12
加速。我做错了什么?
提前谢谢
答案 0 :(得分:0)
根据以下网站 http://www.futurechips.org/thoughts-for-researchers/parallel-programming-gene-amdahl-said.html CPU的数量不应限制为14,您应该将矢量的大小设为n。我们用阿马达尔定律做的是找到算法的精确度,当p变为无穷大时达到这个极限。
答案 1 :(得分:0)
关于使用amdahl定律在regad中并行化此代码的假设不正确您的代码是顺序的,因为amdahl法律关心此部分的增强,因此当您计算第一个循环时,只有20个串行作业中的14个被并行化。然后你的线程到达第二个循环(除非你想将这个代码重组为完整的并行版本)。对于第二个循环,代码的所有部分都可以并行化。现在你应该找到每个增强部分增强到串行部分的百分比,然后找到它的加速。