使用MPI,为什么我的并行代码比我的串行代码慢?

时间:2012-12-08 20:50:06

标签: performance parallel-processing mpi openmpi

通常,并行代码是否可能比串行代码慢?我是,我真的很沮丧!我该怎么办?

2 个答案:

答案 0 :(得分:14)

确定并行模型性能的其他3个关键因素是:

• Parallel task granularity; 
• Communication overhead; 
• Load balancing among processes.

并行任务粒度

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

tl; dr:您的并行任务必须是"大"足以证明并行化的开销。


沟通开销

每次进程打算与其他进程通信时,都会产生创建/发送消息的成本,并且在使用synchronous communication例程的情况下,还需要等待其他进程接收消息的成本。因此,要使用MPI提高应用程序的性能,必须减少进程之间交换的消息量。

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

通过使用性能更高的通信硬件可以提高通信性能,但可能会变得昂贵。集体通信也可以提高通信性能,因为它可以根据硬件,网络和拓扑优化通信。

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


流程之间的负载平衡

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

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

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

其他解决方案是您手动执行任务分配的调整。这可能会变得复杂而艰难。但是,如果资源集不是速度同构的并且在应用程序执行之间不断变化,则任务分发调优的性能可移植性可能会受到威胁。

tl; dr:每个流程都需要大致相同的时间才能完成工作。

答案 1 :(得分:0)

正如其他人所指出的,并行代码可能比串行代码慢的原因有几个。

如果您正在进行矩阵运算,您可能希望通过“阻塞”代码来更有效地利用cpu缓存。根据cpu缓存大小,您可能最多可以获得3到4倍的性能提升。阻塞实质上是在小块或块中处理矩阵,使得它们适合高速缓存存储器。这减少了必须读/写主存储器并导致性能改进。

另一种选择是使用GPU。

以上解决方案适用于大部分计算用于浮点或整数运算的

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