4

我正在开发一个代码来按照我的标准执行一些非常大的计算。根据单 CPU 估计,预期运行时间约为 10 个 CPU 年,内存需求约为 64 GB。几乎不需要 IO。我有问题的代码的串行版本(用 C 编写)运行良好,我必须开始考虑如何最好地并行化代码。

我可以访问具有 ~64 GB RAM 和每个节点 16 个内核的集群。我可能会限制自己使用例如 <= 8 个节点。我正在想象一个设置,其中内存在单个节点上的线程之间共享,不同节点上使用单独的内存,节点之间的通信相对较少。

从我目前阅读的内容来看,我提出的解决方案是使用混合 OpenMP + OpenMPI 设计,使用 OpenMP 管理各个计算节点上的线程,使用 OpenMPI 在节点之间传递信息,如下所示: https:/ /www.rc.colorado.edu/crcdocs/openmpi-openmp

我的问题是这是否是实现这种并行化的“最佳”方式。我是一位经验丰富的 C 程序员,但在并行编程方面的经验非常有限(有点使用 OpenMP,没有使用 OpenMPI;我过去的大部分工作都是令人尴尬的并行)。作为替代建议,OpenMPI 是否可以在单个主机上有效共享内存?如果是这样,那么我可以避免使用 OpenMP,这会使事情变得更简单(一个 API 而不是两个)。

4

1 回答 1

7

混合 OpenMP 和 MPI 编码最适用于可以清楚地识别两个独立并行级别的问题 - 粗粒度一级和嵌套在每个粗略子域内的细粒度一级。由于在使用消息传递实现时,细粒度并行需要大量通信,因此它无法扩展,因为通信开销可以与正在完成的工作量相当。由于 OpenMP 是共享内存范式,不需要数据通信,只需要访问同步,更适合更细粒度的并行任务。OpenMP 还受益于线程之间的数据共享(以及在现代多核 CPU 上共享最后一级缓存的相应缓存共享),并且通常比等效的消息传递代码需要更少的内存,其中一些数据可能需要在所有进程中复制。另一端的 MPI 可以跨节点运行,并且不限于在单个共享内存系统上运行。

您的话表明您的并行化非常粗粒度或属于所谓的尴尬并行问题。如果我是你,我会去混血儿。如果您只使用 OpenMP 编译指示而不使用运行时调用(例如omp_get_thread_num()),您的代码可以编译为纯 MPI(即使用非线程 MPI 进程)或混合编译,具体取决于您是否启用 OpenMP(您也可以提供一个虚拟的 OpenMP 运行时以使代码能够被编译为串行)。这将为您提供 OpenMP(数据共享、缓存重用)和 MPI(透明网络、可扩展性、轻松启动作业)的好处,并添加了关闭 OpenMP 并在仅 MPI 模式下运行的选项。作为额外的奖励,您将能够迎接未来,这看起来就像是让我们相互连接的多核 CPU。

于 2012-09-10T16:34:43.967 回答