3

我的工作假设 MPI 进程从头到尾都在单独和唯一的数据上运行,即使在同一台机器上也是如此。但是我的代码,我希望每个 MPI 进程都有一个全局对象:

class global { // the class };
extern global obj;
global obj;

int main( int argc, char * argv[] ) {
    MPI_Init();

    // determine rank
    std::cout << rank << " global object is at " << &obj << std::endl;

    MPI_Finalize();
}

使用 -np 2,结果:

0 global object is at 0x620740
1 global object is at 0x620740

这可能是分段错误或其他错误的来源,其中两个 MPI 进程正在同一台机器上访问相同的内存地址以获取其自己的全局对象?

编辑:我应该提到,我的意图中的“全局”不是所有 MPI 进程的全局,而是每个单独的 MPI 进程中的全局。

4

1 回答 1

8

MPI 使用同一个可执行文件启动多个进程。通常这会导致那些进程具有相同的初始内存布局,只有堆栈的位置和映射不同共享库的位置可能不同。在您的情况下obj,是一个未初始化的静态对象,因此放置在 BSS 部分中,该部分通常位于初始化数据部分之后。数据量是预先知道的,BSS 部分的位置也是已知的——这些都是由链接器固定的。因此obj,在从该可执行文件创建的每个进程中具有相同的位置。

这对 MPI 来说不是问题,因为每个进程都有自己的虚拟内存空间,并且您看到的地址是虚拟地址,仅在相应进程的虚拟内存空间中有效。换句话说0x620740,rank 0 和0x620740rank 1 是物理内存中完全不同的位置,因为它们都指向两个不同虚拟内存空间中的相同位置。

一般来说,MPI 没有全局(或共享)对象的概念,因为假设 MPI 作业中的每个进程只能访问其自己的隔离内存空间。实际上,当进程在同一个物理节点上运行时,它们可以(而且它们通常会)共享内存(例如,当进程在多核、多处理器或其他类型的共享内存机器上运行时,MPI 通常使用共享内存发送消息),但除非您已经采取了特殊步骤来放入obj一个专门创建的共享内存段,它不会被共享。

于 2013-07-31T18:49:15.513 回答