#include<stdio.h>
#include<mpi.h>
int a=1;
int *p=&a;
int main(int argc, char **argv)
{

MPI_Init(&argc,&argv);

int rank,size;
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
//printf("Address val: %u \n",p);

*p=*p+1;


MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();

printf("Value of a : %d\n",*p);

return 0;
}

在这里,我试图用3个进程来执行程序,每个进程都试图将a的值增加1,因此所有进程执行结束时的值应该是4。那么为什么在mpi_finalize()之后的printf语句中将值打印为2。并行执行不应该在mpi_finalize()停止,并且在它之后应该只有一个进程在运行。那么,为什么在执行过程中我要得到print语句3次,每个进程一次?

最佳答案

认为mpi_init启动请求数量的进程(或使用任何机制实现mpi)而mpi_finalized停止进程是一个常见的误解。最好考虑在一组操作系统进程之上启动mpi系统。mpi标准对mpi实际运行在什么上面以及底层机制是如何启动的保持沉默。实际上,调用mpi_init(或mpiexec)可能会触发所请求的进程数,所有进程在程序启动时都处于活动状态。在调用mpirun之后,进程也可能继续存在,直到程序完成。
这意味着在调用mpi_finalized之前和调用mpi_init之后,很可能有多个o/s进程正在运行,每个进程都在执行同一个程序。这解释了为什么每个进程执行一次mpi_finalize语句。
至于为什么printf的值设置为a而不是2,实际上,您运行的是同一个程序的4副本(其中n是进程数),每个副本都将n添加到自己的1版本中。一个进程内存中的变量与另一个进程内存中同名的变量没有关系。因此,每个进程都将a设置为a
要从一个进程到另一个进程获取任何数据,进程需要进行消息传递。
编辑,回应OP的评论
正如一个进程内存中的变量与另一个进程内存中同名的变量没有关系一样,指针(这是一种变量)与另一个进程内存中同名的指针也没有关系。不要被愚弄,如果“同一”指针在多个进程中有“相同”地址,这些地址在不同的地址空间中并且不相同,则指针不会指向同一个位置。
一个类比:一个商业街,Toytown和一个商业街,Legotown不是同一个地址;地址空间中的名字有一个巧合。
要从一个进程到另一个进程获取任何数据(指针或其他),进程需要参与消息传递。您似乎坚持认为mpi进程以某种方式共享内存。他们不会,放开这个想法。

10-06 05:56
查看更多