2013-09-21 25 views
0

我是一名MPI初学者。我有一个大数组gmat的数字(类型double,尺寸1x14000000),它是预先计算并存储在一个二进制文件中。它将在内存中使用大约100 MB(14000000 x8字节/ 1024/1024)。我想写一个MPI代码,它将在这个数组上进行一些计算(例如,将进程的排名数字乘以gmat的所有元素)。这个数组gmat本身在运行时保持不变。 的代码应该是这样的如何在MPI中使用共享全局数据集?

#include <iostream> 
#include "mpi.h" 
double* gmat; 
long int imax; 

int main(int argc, char* argv[]) 
{ 
void performcomputation(int rank); // this function performs the computation and will be called by all processes 

imax=atoi(argv[1]); // user inputs the length of gmat 

MPI::Init(); 
rank = MPI::COMM_WORLD.Get_rank(); 
size = MPI::COMM_WORLD.Get_size(); //i will use -np 16 = 4 processors x 4 cores 

if rank==0 // read the gmat array using one of the processes 
{ 
gmat = new double[imax]; 
// read values of gmat from a file 
// next line is supposed to broadcast values of gmat to all processes which will use it 
MPI::COMM_WORLD.Bcast(&gmat,imax,MPI::DOUBLE,1);  
} 

MPI::COMM_WORLD.Barrier(); 
performcomputation(rank); 
MPI::Finalize(); 

return 0; 
} 

void performcomputation(int rank) 
{ 
int i; 
for (i=0;i <imax; i++) 
cout << "the new value is" << gmat[i]*rank << endl; 
}  

我的问题是,当我使用运行16个进程(-np 16)这段代码,是GMAT同样为所有的人?我的意思是,代码将使用16 x 100 MB的内存来存储每个进程的gmat,还是只使用100 MB,因为我已经将gmat定义为全局的?我不希望不同的进程从文件中读取gmat,因为阅读这么多的数字需要时间。有什么更好的方法来做到这一点?谢谢。

回答

1

首先,请不要使用MPI C++绑定。这些在MPI-2.2中被弃用,然后在MPI-3.0中删除了,因此不再是规范的一部分,这意味着未来的MPI实现甚至不需要提供C++绑定,如果他们这样做,他们可能会分歧在界面看起来像。

这就是说,你的代码中包含一个非常常见的错误:

if rank==0 // read the gmat array using one of the processes 
{ 
    gmat = new double[imax]; 
    // read values of gmat from a file 
    // next line is supposed to broadcast values of gmat to all processes which will use it 
    MPI::COMM_WORLD.Bcast(&gmat,imax,MPI::DOUBLE,1);  
} 

因为有四大误区这儿,这是行不通的。首先,gmat只在等级0上分配,而不在其他等级中分配,这不是你想要的。其次,你给Bcast指针gmat的地址,而不是它指向的数据的地址(即你不应该使用&运算符)。您还从广播级别0广播,但将1作为广播根参数进行广播。但是最重​​要的错误是MPI_BCAST是一个集体通信呼叫,并且所有等级都需要用与root参数相同的值调用它以便成功完成。正确的代码(使用C绑定的不是C++的)是:

gmat = new double[imax]; 

if (rank == 0) 
{ 
    // read values of gmat from a file 
} 
MPI_Bcast(gmat, imax, MPI_DOUBLE, 0, MPI_COMM_WORLD); 
//  ^^^^     ^^^ 
//  no &    root == 0 

每个等级都有自己的gmat副本。最初所有值都不相同(例如随机或全零,取决于内存分配器)。在广播之后,所有副本将与等级0的gmat副本相同。在呼叫performcomputation()之后,每个副本将会不同,因为每个副本将gmat的元素与不同的数字相乘。你的问题的答案是:代码将使用100 MiB 每个级别,因此总共16 x 100 MiB。

MPI处理分布式内存 - 进程不共享变量,无论它们是本地还是全局变量。共享数据的唯一方式是使用像点对点通信(例如MPI_SEND/MPI_RECV),集体呼叫(例如MPI_BCAST)或单向通信(例如MPI_PUT/MPI_GET)的MPI呼叫。

+0

感谢一吨:)正在等待您的回复。会记住你的观点。 – Guddu

相关问题