我的工作假设是 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 进程中的全局。
最佳答案
MPI 使用同一个可执行文件启动多个进程。通常这会导致这些进程具有相同的初始内存布局,只有堆栈的位置和不同共享库映射的位置可能不同。在您的情况下 obj
是一个未初始化的静态对象,因此放置在 BSS 部分中,该部分通常位于初始化数据部分之后。数据量和 BSS 部分的位置都是预先知道的——这些都是由链接器确定的。因此 obj
在从该可执行文件创建的每个进程中具有相同的位置。
这对 MPI 来说不是问题,因为每个进程都有自己的虚拟内存空间,并且您看到的地址是虚拟地址,仅在相应进程的虚拟内存空间中有效。换句话说,等级 0 中的 0x620740
和等级 1 中的 0x620740
是物理内存中完全不同的位置,因为它们都指向两个不同虚拟内存空间中的相同位置。
一般来说,MPI 没有全局(或共享)对象的概念,因为根据假设,MPI 作业中的每个进程只能访问其自己的独立内存空间。实际上,当进程在同一物理节点上运行时,它们可以(而且它们通常会这样做)共享内存(例如,当进程在多核、多处理器或其他类型的共享内存机器上运行时,MPI 通常使用共享内存发送消息),但除非您已采取特殊步骤将 obj
放入专门创建的共享内存段,它不会被共享。
关于c++ - MPI 和全局对象 : All ranks have the object at same memory address?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17978222/