我正在开发一个代码,按照我的标准执行一些非常大的计算。根据单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而不是两个)。
答案 0 :(得分:6)
混合OpenMP和MPI编码最适合于能够清楚地识别两个不同级别的并行性的问题 - corase grained one和细粒度并行嵌套在每个粗子域内。由于细粒度并行性在通过消息传递实现时需要大量通信,因此它不能扩展,因为通信开销可以与正在完成的工作量相当。由于OpenMP是一种共享内存范例,因此不需要数据通信,只需访问同步,并且更适合于更细粒度的并行任务。 OpenMP还受益于线程之间的数据共享(以及具有共享最后一级缓存的现代多核CPU上的相应缓存共享),并且通常比等效的消息传递代码需要更少的内存,其中一些数据可能需要在所有过程。另一方面,MPI可以运行跨节点,并且不限于在单个共享内存系统上运行。
你的话表明你的并行化非常粗糙或属于所谓的令人难以置信的并行问题。如果我是你,我会去杂交。如果您只使用OpenMP pragma并且不使用运行时调用(例如omp_get_thread_num()
),则可以将代码编译为纯MPI(即使用非线程MPI进程)或混合编译,具体取决于您是启用OpenMP还是not(您还可以提供一个虚拟的OpenMP运行时,以使代码能够编译为串行代码)。这将为您提供OpenMP(数据共享,缓存重用)和MPI(透明网络,可伸缩性,轻松启动作业)的好处,并添加了关闭OpenMP并以仅MPI模式运行的选项。作为额外的奖励,您将能够满足未来,这看起来像让我们互相连接许多核心CPU。