MPI和全局变量

MPI和全局变量,mpi,Mpi,我必须实施MPI计划。有一些全局变量(4个浮点数数组和其他6个单浮点变量)首先由从文件读取数据的主进程进行序列化。然后我调用MPI_Init,当秩0的进程等待结果时,其他进程(秩1,2,3,4)处理数组等。。。 问题是这些数组似乎不再被初始化,所有数组都设置为0。我试图在主函数中移动全局变量,但结果是一样的。调用MPI_Init()时,所有进程都是由fork创建的,对吗?所以每个人都有父亲的记忆副本,为什么他们看不到初始化数组?我担心你误解了 最好将每个MPI进程视为一个独立的程序,尽管它与计算

我必须实施MPI计划。有一些全局变量(4个浮点数数组和其他6个单浮点变量)首先由从文件读取数据的主进程进行序列化。然后我调用MPI_Init,当秩0的进程等待结果时,其他进程(秩1,2,3,4)处理数组等。。。
问题是这些数组似乎不再被初始化,所有数组都设置为0。我试图在主函数中移动全局变量,但结果是一样的。调用MPI_Init()时,所有进程都是由fork创建的,对吗?所以每个人都有父亲的记忆副本,为什么他们看不到初始化数组?

我担心你误解了

最好将每个MPI进程视为一个独立的程序,尽管它与计算中的其他进程具有相同的源代码。进程0对其地址空间中的变量执行的操作对其他进程的地址空间的内容没有影响

我不确定MPI标准是否要求进程0具有在调用
MPI_init
之前声明和初始化的变量值,也就是在进程0真正存在之前

不管是否需要,您都必须编写代码,将值放入其他进程地址空间中的变量中。一种方法是让进程0逐个或使用广播将值发送到其他进程。另一种方法是让所有进程从输入文件中读取值;如果选择此选项,请注意对i/o资源的争用

顺便说一下,我认为MPI实现在调用
MPI_init
时通过分叉来创建进程并不常见,分叉更常用于创建线程。我认为大多数MPI实现实际上是在调用
mpiexec
时创建进程的,调用
MPI_init
是宣布程序开始并行计算的形式

调用MPI_Init()时,所有进程都是由fork创建的,对吗

错。


MPI生成程序的多个实例。这些实例是独立的进程,每个进程都有自己的内存空间。每个进程都有自己的每个变量副本,包括全局变量
MPI_Init()
只初始化MPI环境,以便调用其他MPI函数。

正如其他答案所说,MPI不是这样工作的。数据对于每个进程都是唯一的,必须使用MPI规范中提供的API在进程之间显式传输

然而,有些编程模型允许这种行为。如果说并行计算,是指一个处理器上有多个核,那么使用类似于在线程之间共享数据的方法可能会更好

或者,如果您确实需要使用多个处理器(可能是因为您的数据太大,无法装入一个处理器的内存,或者是其他原因),您可以查看一种并行全局地址空间(PGAS)语言。在这些模型中,您拥有对执行中的所有进程全局可用的内存

最后,MPI的一部分允许您将内存从一个进程公开给其他进程。这是远程内存访问(RMA)或单边章节。它可能很复杂,但如果这正是您所需要的计算模型的话,它会很强大


所有这些模型都需要更改应用程序的工作方式,但听起来它们可能更适合您的问题。

您的答案非常有用。我必须将此练习作为并行编程课程的一个小项目来实施,老师希望我们使用mpi(可能更好的是openmp)…该程序应计算100个球体的总体积,这些球体均匀分布在x、y、z三个方向上,并给定它们的光线,并使用蒙特卡罗算法(近似值)。所有这些数据在开始时都被插入到4个不同的数组中,我认为每个进程都应该有它们的副本…好吧,我将使用广播。谢谢你…你对我真的很好。所以最好的解决方案是进程0初始化数组,然后把它们传给其他进程,不是吗?我担心这对于并行计算来说是浪费时间…对于并行计算机来说可能是浪费时间,但是在你了解这个主题的过程中要充分利用你的时间。所以最好的解决方案是进程0初始化数组,然后他将它们传给其他进程,不是吗?我担心这对于并行计算来说是浪费时间…在阅读了一些评论之后,我发现这实际上是一个类的练习,所以改变模型不是一个选项,但对于后代来说,有这个答案仍然是很好的,这是SE的重点。请回答另一个问题:所有进程/列组都应该在最小值和最大值之间创建不同的随机浮点数(由我给出),但如果我启动mpirun-np 5/程序,所有进程/列组都会生成相同的随机浮点数…如何避免它?这应该作为一个单独的问题来问。这并不是MPI特有的。事实上,已经有人问过并回答过了,例如: