9

一般来说,并行代码是否可能比串行代码慢?我的是,我真的很沮丧!我能做些什么?

4

2 回答 2

18

其中,决定并行模型性能的 3 个关键因素是:

  • 并行任务粒度;
  • 通信开销;
  • 进程之间的负载平衡。

并行任务粒度

并行任务的粒度必须足够大以超过并行的开销(例如,并行任务的创建和它们之间的通信)。由于分布式内存 (DM) 模型中进程的通信开销通常高于线程同步,因此进程应该具有更高的任务粒度。这种粒度也不应该危及负载平衡。

tl; dr:您的并行任务必须“大”到足以证明并行化的开销是合理的。


通信开销

每当一个进程打算与其他进程通信时,它都有创建/发送消息的成本,而在synchronous communication例程的情况下,还有等待其他进程接收消息的成本。因此,要使用 MPI 提高应用程序的性能,有必要减少进程之间交换的消息数量。

您可以在进程之间使用计算冗余,而不是等待一个特定进程的结果,这个结果可以直接在每个进程中执行。当然,当交换结果的开销与计算本身所花费的时间重叠时,这通常是合理的。另一种解决方案是替换synchronous communicationasynchronous communication. 在synchronous communication发送消息的进程中等待直到另一个进程收到它,在asynchronous communication进程中从发送调用返回后立即恢复执行。因此,与计算重叠的通信。但是,要利用asynchronous communication它可能需要重写代码,也可能仍然难以实现良好的重叠率。

通过使用更高性能的通信硬件可以减少通信开销,但它可能会变得昂贵。集体通信还可以提高通信性能,因为它基于硬件、网络和拓扑优化了通信。

tl;dr:减少并行任务之间的通信和同步量。使用:冗余计算、异步通信、集体通信和更快的通信硬件。


进程间负载均衡

良好的负载平衡是必不可少的,因为它可以最大限度地并行完成工作。负载平衡受进程之间的任务分配和应用程序运行的资源集的影响。

在一组固定资源中运行的应用程序中,您应该专注于任务分配。如果任务具有大致相同的计算量(例如,对于迭代),那么只需要在进程之间执行最平等的任务分配。

但是,某些应用程序可能在具有不同速度的处理器的系统中运行,或者它可能具有具有不同计算量的子任务。对于这种情况,为了促进更好的负载平衡,farming model可以使用任务,因为它可以通过动态任务分配来实现。但是,在此模型中,使用的通信量可能会危及效率。

另一种解决方案是您手动执行任务分配的调整。这可能会变得复杂而困难。但是,如果资源集的速度不是同质的并且在应用程序执行之间不断变化,则可能会危及任务分配调整的性能可移植性。

tl; dr:每个过程应该花费大约相同的时间来完成他们的工作。

于 2012-12-09T05:19:25.663 回答
0

正如其他人指出的那样,并行代码比串行代码慢的原因有很多。

如果您正在执行矩阵运算,您可能希望通过“阻塞”代码更有效地利用 cpu 缓存内存。根据 cpu 缓存大小,您可能会获得高达 3 到 4 倍的性能提升。分块本质上是处理小块或块中的矩阵,以使它们适合高速缓存。这减少了读取/写入主内存的次数并提高了性能。

另一种选择是使用 GPU。

在大部分计算用于浮点或整数运算的情况下,上述解决方案效果很好

对于通用计算,理想情况下,您希望将应用程序设计为自适应的,以便在运行时确定分配工作负载是否有性能提升,并且仅在有利时才分配。

于 2012-12-10T02:59:26.063 回答