【问题标题】:MPI and global object: All ranks have the object at same memory address?MPI 和全局对象:所有等级的对象都在同一个内存地址?
【发布时间】:2013-08-01 10:35:40
【问题描述】:

我的工作假设 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 进程中的全局。

【问题讨论】:

  • 是虚拟空间中相同的内存地址。如果执行: $ nm executable_file | grep 对象;您会在二进制文件中看到该地址编码

标签: c++ mpi


【解决方案1】:

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

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

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

【讨论】:

  • 啊,我明白了。感谢您的详尽解释,它消除了我的一些基本误解。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-08
  • 2023-02-07
  • 2010-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-07
相关资源
最近更新 更多