使用MPI更改变量的值 #包括 #包括 INTA=1; int*p=&a; int main(int argc,字符**argv) { MPI_Init(&argc,&argv); int等级、大小; MPI通信等级(MPI通信世界和等级); MPI_通信大小(MPI_通信世界和大小); //printf(“地址值:%u\n”,p); *p=*p+1; MPI_屏障(MPI_通信世界); MPI_Finalize(); printf(“a的值:%d\n”,*p); 返回0; }

使用MPI更改变量的值 #包括 #包括 INTA=1; int*p=&a; int main(int argc,字符**argv) { MPI_Init(&argc,&argv); int等级、大小; MPI通信等级(MPI通信世界和等级); MPI_通信大小(MPI_通信世界和大小); //printf(“地址值:%u\n”,p); *p=*p+1; MPI_屏障(MPI_通信世界); MPI_Finalize(); printf(“a的值:%d\n”,*p); 返回0; },c,mpi,C,Mpi,在这里,我尝试用3个进程执行程序,其中每个进程都尝试将a的值增加1,因此所有进程执行结束时的值应该是4。那么,为什么在MPI_Finalize()之后的printf语句中只将值打印为2呢。并行执行不是在MPI_Finalize()处停止,并且应该只有一个进程在它之后运行吗。那么为什么在执行过程中,我要得到print语句3次,每个进程一次 认为mpi_init启动所请求数量的进程(或用于实现mpi的任何机制),而mpi_finalized停止它们,这是一种常见的误解。最好考虑在一组操作系统进程之上

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

认为
mpi_init
启动所请求数量的进程(或用于实现mpi的任何机制),而
mpi_finalized
停止它们,这是一种常见的误解。最好考虑在一组操作系统进程之上启动mpi系统。MPI标准没有说明MPI实际运行在什么之上,以及底层机制是如何启动的。实际上,调用
mpiexec
(或
mpirun
)可能会启动所请求的进程数,当程序启动时,所有进程都处于活动状态。调用
mpi\u finalized
后,这些进程也可能继续运行,直到程序完成

这意味着在调用
mpi_init
之前和调用
mpi_finalize
之后,可能有许多o/s进程正在运行,每个进程都执行相同的程序。这解释了为什么对每个进程执行一次
printf
语句

至于为什么
a
的值被设置为
2
而不是
4
,实际上,您运行的是同一程序的
n
副本(其中
n
是进程数),每个副本将
1
添加到自己版本的
a
。一个进程内存中的变量与另一个进程内存中同名的变量没有关系。因此,每个进程都将
a
设置为
2

要从一个进程到另一个进程获取任何数据,这些进程需要进行消息传递

编辑,回应OP的评论

正如一个进程内存中的变量与另一个进程内存中同名的变量没有关系一样,指针(这是一种变量)与另一个进程内存中同名的指针没有关系。不要被愚弄了,如果“相同”指针在多个进程中具有“相同”地址,则这些地址位于不同的地址空间中并且不相同,指针不会指向相同的位置

打个比方:Toytown高街1号与Legotown高街1号的地址不同;地址空间中的名字有一个巧合


要从一个进程到另一个进程获取任何数据(指针或其他),进程需要进行消息传递。您似乎坚持认为MPI进程以某种方式共享内存。他们没有,放开这个概念。

因为MPI只提供在不同进程之间通信的选项,所以您必须进行消息传递。出于您的目的,有类似MPI_Allreduce的东西,它可以通过单独的进程对数据求和。请注意,这会添加值,因此在您的情况下,您希望对增量求和,然后将总和添加到p:

#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;
}

在您的实现中,派生线程之间没有通信。每个进程都有自己的
int a
变量,该变量递增并打印到屏幕上。使变量成为全局变量并不能使它在进程之间共享,所有的指针噱头都告诉我,你不知道自己在做什么。我建议在你继续之前多学一点C语言和操作系统

无论如何,您必须让流程进行通信。下面是一个示例的样子:

int inc = 1;
MPI_Allreduce(MPI_IN_PLACE, &inc, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
*p += inc;
#包括
#包括
//此程序将以一种“非常”糟糕的方式计算派生进程的数量
int main(int argc,字符**argv)
{
int部分=1;
整数和;
int my_id=0;
//让我们假设id为0的进程是根进程
int root_进程=0;
//繁殖过程等。
MPI_Init(&argc,&argv);
//每个进程都知道自己的id
MPI通信等级(MPI通信世界和我的id);
//所有进程都将其“部分”添加到“总和”中
MPI_Reduce(部分和总和、1、MPI_INT、MPI_总和、根进程、MPI_COMM_WORLD);
//从头MPI
MPI_Finalize();
//根进程传递求和结果
if(my_id==根进程)
{
printf(“总和:%d\n”,总和);
}
返回0;
}

谢谢。您关于创建的进程数的回答很好,但是关于为什么将值设置为2 only的回答仍然不能满足我的要求。因为,我尝试为每个进程打印指针p中存储的内存位置(请参见注释行)。它为所有进程显示相同的值。这意味着,即使该程序的三个实例正在为这三个进程运行,它们在内存中都显示相同的“a”地址。这怎么可能呢?因为您的进程(所有进程)都使用虚拟地址。它们在所有进程中都可以相同,但由于操作系统的分页系统,它们都指向不同的内存位置。在多个进程之间共享信息(即“a”变量的当前值)的唯一方法是通过消息传递。这就是MPI的要点。
#include<stdio.h>
#include<mpi.h>

// this program will count the number of spawned processes in a *very* bad way
int main(int argc, char **argv)
{
   int partial = 1;
   int sum;
   int my_id = 0;

   // let's just assume the process with id 0 is root
   int root_process = 0;

   // spawn processes, etc.
   MPI_Init(&argc,&argv);

   // every process learns his id
   MPI_Comm_rank(MPI_COMM_WORLD, &my_id);

   // all processes add their 'partial' to the 'sum'
   MPI_Reduce(&partial, &sum, 1, MPI_INT, MPI_SUM, root_process, MPI_COMM_WORLD); 

   // de-init MPI
   MPI_Finalize();

   // the root process communicates the summation result
   if (my_id == root_process)
   {
      printf("Sum total : %d\n", sum);
   }

   return 0;
}