MPI中主进程更新的全局变量无法在从进程访问的问题求助
问题原因
MPI中每个进程都是独立的执行实例,拥有完全独立的内存空间。哪怕你把total_b_points声明为全局变量,每个进程也会持有这个变量的私有副本。主进程(pid=0)修改的只是自身内存里的变量值,从进程的变量副本不会自动同步,所以从进程里它始终是初始值0。
解决方案
下面提供两种常用的同步方法:
方法1:使用MPI_Bcast(广播,推荐)
广播是MPI专门用于单进程向通信域内所有其他进程发送数据的操作,非常适合这种一对多的数据同步场景。
修改后的代码:
#include <iostream> #include <mpi.h> #include<string> #include <bits/stdc++.h> int total_b_points=0; int main(int argc, char * argv[]){ MPI_Init(&argc,&argv); int pid; int np; MPI_Comm_size(MPI_COMM_WORLD, &np); MPI_Comm_rank(MPI_COMM_WORLD, &pid); if(pid==0){ std::vector<double> values ={33,334,5,43}; total_b_points = values.size(); std::cout << "The value of total_b_points= " <<total_b_points<< std::endl; } // 主进程把total_b_points广播给所有进程(包括自身,无影响) MPI_Bcast(&total_b_points, 1, MPI_INT, 0, MPI_COMM_WORLD); // 从进程输出同步后的值 if(pid!=0){ std::cout << "Printing the value of total_b_points in Slave "<< total_b_points<< std::endl; } MPI_Finalize(); }
MPI_Bcast参数说明:
&total_b_points:要发送/接收的数据地址1:数据元素个数MPI_INT:数据类型0:发送数据的根进程(即主进程pid=0)MPI_COMM_WORLD:目标通信域
方法2:使用MPI_Send/MPI_Recv(点对点通信)
如果只需要给特定从进程发送数据,可以用点对点的收发操作,由主进程单独给每个从进程发送值:
修改后的代码:
#include <iostream> #include <mpi.h> #include<string> #include <bits/stdc++.h> int total_b_points=0; int main(int argc, char * argv[]){ MPI_Init(&argc,&argv); int pid; int np; MPI_Comm_size(MPI_COMM_WORLD, &np); MPI_Comm_rank(MPI_COMM_WORLD, &pid); if(pid==0){ std::vector<double> values ={33,334,5,43}; total_b_points = values.size(); std::cout << "The value of total_b_points= " <<total_b_points<< std::endl; // 主进程给每个从进程逐一发送数据 for(int i=1; i<np; i++){ MPI_Send(&total_b_points, 1, MPI_INT, i, 0, MPI_COMM_WORLD); } } else{ // 从进程接收主进程的数据 MPI_Recv(&total_b_points, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); std::cout << "Printing the value of total_b_points in Slave "<< total_b_points<< std::endl; } MPI_Finalize(); }
运行结果说明
使用上述任意一种方法后,从进程输出的total_b_points都会同步为4,与主进程的值一致。
内容的提问来源于stack exchange,提问作者mchaudh4
相关产品推荐
相关产品推荐

