我有一个简单的 DO 循环(Fortran 90),其中各个迭代彼此独立,并且仅从硬盘驱动器输入/输出数据(进程之间不交换消息/MPI),我已经并行化了使用 MPI。在顺序运行中,循环的一次迭代大约需要一天才能完成。如果我并行运行 29 次这样的迭代,大约需要 2.5 天。它位于超级计算机的一个节点上(即没有节点间通信)。
我听说有人告诉过,如果是可并行化的程序(循环中的独立步骤),总执行时间应该大约接近在循环中只运行一个步骤时的执行时间。
问题:你觉得这种加速效果好吗?
非常感谢。
我有一个简单的 DO 循环(Fortran 90),其中各个迭代彼此独立,并且仅从硬盘驱动器输入/输出数据(进程之间不交换消息/MPI),我已经并行化了使用 MPI。在顺序运行中,循环的一次迭代大约需要一天才能完成。如果我并行运行 29 次这样的迭代,大约需要 2.5 天。它位于超级计算机的一个节点上(即没有节点间通信)。
我听说有人告诉过,如果是可并行化的程序(循环中的独立步骤),总执行时间应该大约接近在循环中只运行一个步骤时的执行时间。
问题:你觉得这种加速效果好吗?
非常感谢。
因此,当您的代码扩展到 29 个并行副本时,您的运行速度只有您希望的一半?
内存带宽可能是一个问题,同一算法的 29 个副本同时读取/写入自己的内存。这就是为什么在这种情况下,在单个迭代中寻找并行性可能会更好(但更难)。
让我们使用视频编码作为“一次迭代”可能的具体示例。例如,并行编码 29 个视频就像 OP 的提议一样。让 x264 使用 32 个内核对一个视频进行编码,然后为接下来的 28 个视频重复此操作,使用更少的总 RAM,并且缓存更好。
在实践中,可能并行 2 或 3 个 vid,每个使用 10 到 16 个线程,会很好,因为 x264 可以找到多少并行性是有限的。
这取决于算法,以及它与多个线程的扩展程度。如果根本没有,或者你没有时间编写代码,那么一路蛮力。超过 10 倍的加速是毫不费力的。(例如,使用GNU在不同的数据集上运行单线程程序,make -j29
或者在您的情况下在单个程序中使用多个线程。:)parallel
当您的代码运行时,您可以检查 CPU 利用率,以确保您保持 29 个 CPU 内核的忙碌,就像您尝试的那样。您还可以使用分析工具(如 Linux perf
)来研究缓存效果。如果并行运行的数据缓存未命中率是单线程运行的 29 倍以上,这将开始解释问题。
由于您有独立的迭代,因此在 29 个内核上进行 29 次迭代的运行时间不应与在单个内核上进行单次迭代的运行时间相差无几。除非以下一个或多个条件适用,否则您应该接近一天: