通常,并行代码是否可能比串行代码慢?我是,我对此感到非常沮丧!我能做什么?
最佳答案
其中,决定并行模型性能的3个关键因素是:
并行任务粒度
并行任务的粒度必须足够大以覆盖并行性的开销(例如,并行任务的创建和它们之间的通信)。因为在分布式内存(DM)模型中,进程的通信开销通常比线程同步更高,所以进程应具有更高的任务粒度。这种粒度也不应危害负载平衡。
tl;博士:您的并行任务必须足够“大”以证明并行化的开销。
通讯开销
每当一个进程打算与其他进程进行通信时,就会有创建/发送消息的开销,对于
synchronous communication
例程,还会有等待其他进程接收消息的开销。因此,要使用MPI提高应用程序的性能,必须减少进程之间交换的消息数量。您可以在进程之间使用计算冗余,而不是等待一个特定进程的结果,而是可以在每个进程中直接执行此结果。当然,当交换结果的开销与计算本身所花费的时间重叠时,这通常是合理的。另一种解决方案是将
synchronous communication
替换为asynchronous communication
。在synchronous communication
中,发送消息的进程等待直到另一个进程接收到它,而在asynchronous communication
中,该进程从发送调用返回后立即恢复其执行。因此,通信与计算重叠。但是,要利用asynchronous communication
可能需要重写代码,但仍然可能难以实现良好的重叠率。通过使用高性能的通信硬件可以减少通信开销,但是结果却很昂贵。集体通信还可以改善通信性能,因为它可以基于硬件,网络和拓扑优化通信。
tl; dr:减少并行任务之间的通信和同步量。使用:冗余计算,异步通信,集体通信和更快的通信硬件。
进程之间的负载平衡
良好的负载平衡至关重要,因为它可以最大程度地并行完成工作。负载平衡受进程之间的任务分配以及应用程序正在运行的资源集的影响。
在以一组固定的资源运行的应用程序中,您应集中精力进行任务分配。如果任务具有大致相同的计算量(例如,对于迭代),则仅需要在进程之间执行任务的最均等分配。
但是,某些应用程序可能在带有不同速度处理器的系统中运行,或者可能具有具有不同计算量的子任务。对于这种情况,为了促进更好的负载平衡,可以使用任务
farming model
,因为它可以通过动态任务分配来实现。但是,在此模型中,使用的通信量可能会损害效率。另一个解决方案是您手动执行任务分配的调整。事实证明这可能很复杂而且很困难。但是,如果资源集的速度不均一,并且在应用程序执行之间不断变化,则可能会损害任务分配调整的性能可移植性。
tl; dr:每个过程应花费大约相同的时间来完成其工作。
关于performance - 为什么并行代码比串行代码慢?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13781815/