什么操作导致并行代码运行缓慢?

rad*_*att 3 parallel-processing erlang

阅读本文:Hitchhiker的并发指南,更具体地说,关于Amdahl定律的部分- 并行程序的速度与其最慢的部分一样快,并且程序从一开始就越平行就越快.引入更多内核,我发现自己在想:如何确保从头开始编写尽可能并行的代码?如何确保我的代码能够获得添加多个内核的最大好处?而且,哪种操作会导致代码不并行,或者并行代码变慢?代码示例当然会受到赞赏.

Orb*_*ing 5

并非所有代码都能够并行运行.

并行执行同时意味着同时进行.如果代码不依赖于与其一起运行的其他代码的最终结果,则代码只能同时运行.如果你正在做这样的等式:

((((x+y)+z)+a)*b)

必须在下一阶段之前计算每个括号,因此无法按顺序执行操作.为了使程序并行,重要的是确定何时存在可以分成可以同时完成的大型任务的大型任务.

考虑总结,我需要加上100,000个数字.

sum = 0;
for (i = 0; i < 100000; i++) {
   sum += numbers[i];
}
Run Code Online (Sandbox Code Playgroud)

添加的交换和传递,a + b + c + d可以被分裂(a + b + c) + d,a + (b + c) + d,(a + b) + (c + d),等最后一种情况是均匀分布的工作,一半在一个支架上,一半在其他.

所以假设我们做了这样的大任务:

sumA = 0;
for (i = 0; i < 100000 / 2; i++) {
   sumA += numbers[i];
}

sumB = 0;
for (i = 100000 / 2; i < 100000; i++) {
   sumB += numbers[i];
}

sum = sumA + sumB;
Run Code Online (Sandbox Code Playgroud)

分成两部分,两个循环可以同时运行并仍然得到相同的答案,我们只需要在最后重新组合.

在并行编程中,这是关键,将工作分成每个工作人员(cpu/node/machine)的部分,然后收集结果并汇总最终结果.我们称之为散射和聚集.

许多计算任务可以分开,有些则不能.一个非常适合分裂的程序是理想的并行,一个不是,不是.还要考虑散射和收集,分割数据,重组数据(可能转移数据)存在巨大的开销 - 并不总是值得划分任务.

所以,回答你的问题.你可以做的不是让你的程序并行,而是你的程序是否自然能够如此.

  • 当然,((((x + y)+ z)+ a)*b)可以并行化,它与b*(a + x)+ b*(y + z)相同.我指出这一点,并不是因为我不同意你的第一句话,而是因为你所选择的例子很好地说明了许多许多显然是连续的计算,如果分析得当,可以并行. (5认同)
  • @Mark:嗯,是的,公平竞争,可以重新排列,我想在括号中任意一些本来顺序的东西,并在不考虑运算符或其他任何东西的情况下编写它 - 括号是重要的部分.应该使用一般操作符号或函数 - 但不希望使示例*看起来*比需要的更复杂.因此这个超级简单的例子. (3认同)