我有一个可在多个计算节点上运行的大规模代码,可运行在许多CPU内核上。代码使用C++并与OpenMPI并行。用于复杂对象的MPI共享内存
我的代码有一个非常大的对象(〜10GB内存使用量),它是由每个MPI进程读取的。该对象偶尔会更新(可以通过单个进程完成,只需读取数据文件即可)。
我到目前为止一直在做的是给每个MPI过程一个这个对象的副本;但这意味着我受到严格的RAM限制,无法使用节点的全部CPU功能。所以,我一直在阅读有关MPI 3规范中的共享内存。
我的问题是:跨MPI流程共享复杂对象的最佳方式是什么?在我发现的所有例子中,创建了MPI共享内存窗口并用于交换简单的数据结构(浮点数,整数数组等等)。我的全局对象是一个自定义类类型,它包含许多成员变量,其中一些是指针,其中许多是其他复杂的类类型。因此,我觉得我不能只调用MPI_Win_allocate_shared
并传递我复杂对象的地址,特别是因为我想分享有关成员变量的所有信息(特别是,我想分享基础值指针类型成员变量 - 即在MPI进程之间共享“深度拷贝”,每个进程中所有虚拟内存地址都是正确的)。
是否有可能通过MPI共享内存实现这种“深度共享”,如果有,是否有这样做的“最佳实践”?或者,另一个库(例如boost进程)是否使这对我更加可行/直接?
P.S.如果我找不到一个好的解决方案,我会采用混合MPI + pthreads方法,我知道我可以在每个节点上用pthreads轻松地创建这个全局对象。但我真的希望找到一个优雅的MPI专用解决方案。
指向一个进程的虚拟地址空间的指针在其他进程中没有意义,除非共享内存映射到完全相同的基址。你想要的并不是不可能实现的:它可以归结为在所有进程的所有内存空间中找到一个足够大的空洞,并且使用首选地址调用mmap(),但既不可移植也不保证每个每次。正确的解决方案是使用相对指针并在取消引用前将基地址添加到每个指针的值。 –
请注意,当底层通信器的进程组跨越多个共享内存节点时,无法使用'MPI_Win_allocate_shared'。在这种情况下,应该使用通常的MPI RMA。 –
我的计划是像你说的那样使用RMA为每个节点获取一个对象的副本,然后在每个节点上使用共享内存,因此每个节点只有一个对象的副本(这足以保留我的内存使用量最小 - 只需要避免在1个节点上有n个副本。)另外,我正在寻找一个有保证的可移植解决方案(该代码需要可靠工作,并且理想情况下也应该在Linux和Windows上运行)。当你说“正确的解决方案是...”时,你能否更详细地解释这种技术如何解决我的问题?任何伪/示例代码也会有所帮助。谢谢! – davewy