C++ 我可以使用共享内存的MPI吗

C++ 我可以使用共享内存的MPI吗,c++,multithreading,mpi,C++,Multithreading,Mpi,我已经为高度并行化的执行编写了一个模拟软件,使用MPI进行节点间并行化,使用线程进行节点内并行化,以尽可能使用共享内存来减少内存占用。(最大的数据结构大多是只读的,因此我可以轻松地管理线程安全。) 虽然我的程序运行得很好(最后),但对于这种方法是否真的是最好的,我还有第二个想法,主要是因为管理两种类型的并行确实需要一些杂乱无章的异步代码 我发现()为MPI引入了共享内存扩展,允许在单个节点上的MPI并行化中使用共享数据结构 我对MPI不是很有经验,所以我的问题是:这在最近的标准开放MPI实现中可

我已经为高度并行化的执行编写了一个模拟软件,使用MPI进行节点间并行化,使用线程进行节点内并行化,以尽可能使用共享内存来减少内存占用。(最大的数据结构大多是只读的,因此我可以轻松地管理线程安全。)

虽然我的程序运行得很好(最后),但对于这种方法是否真的是最好的,我还有第二个想法,主要是因为管理两种类型的并行确实需要一些杂乱无章的异步代码

我发现()为MPI引入了共享内存扩展,允许在单个节点上的MPI并行化中使用共享数据结构

我对MPI不是很有经验,所以我的问题是:这在最近的标准开放MPI实现中可能吗?在哪里可以找到关于如何实现的介绍/教程


请注意,我不是在谈论如何使用共享内存完成消息传递,我知道MPI可以做到这一点。我想从多个MPI处理器(读取)访问内存中的同一对象。

这可以完成-下面是一个测试代码,它在每个共享内存节点上设置了一个小表。只有一个进程(节点秩0)实际分配和初始化该表,但节点上的所有进程都可以读取该表(对格式设置表示歉意-似乎是空间/选项卡问题)

#包括
#包括
#包括
内部主(空)
{
int i,旗帜;
int nodesize,noderank;
整数大小,等级,irank;
int tablesize,localtablesize;
int*table,*localtable;
int*模型;
MPI_Comm allcomm、nodecomm;
char verstring[MPI_MAX_LIBRARY_VERSION_STRING];
char nodename[MPI_MAX_PROCESSOR_NAME];
MPI_不是winsize;
int windisp;
int*winptr;
int版本,subversion,verstringlen,nodestringlen;
allcomm=MPI_COMM_WORLD;
MPI_Win wintable;
表大小=5;
MPI_Init(NULL,NULL);
MPI通信大小(所有通信和大小);
MPI通信等级(所有通信和等级);
MPI_获取_处理器_名称(节点名称和节点名称);
MPI_获取_版本(&version,&subversion);
MPI获取库版本(verstring和verstringlen);
如果(秩==0)
{
printf(“版本%d,subversion%d\n”,版本,subversion);
printf(“库\n”,verstring);
}
//创建节点本地通信器
MPI_通信_分割_类型(所有通信,MPI_通信_类型共享,等级,
MPI_INFO_NULL和nodecom);
MPI通信大小(节点尺寸和节点尺寸);
MPI通信等级(节点通信和节点连接);
//只有节点上的秩0实际分配内存
localtablesize=0;
如果(noderank==0)localtablesize=tablesize;
//调试信息
printf(“秩%d,共%d个,节点中秩%d,本地表大小%d\n”,
秩、大小、节点名、节点大小、节点名称、本地表大小);
MPI_Win_allocate_shared(localtablesize*sizeof(int)、sizeof(int),
MPI_INFO_NULL、nodecom、localtable和wintable);
MPI_Win_get_attr(wintable、MPI_Win_模型、模型和标志);
如果(1!=标志)
{
printf(“未定义属性MPI_WIN_MODEL\n”);
}
其他的
{
if(MPI_WIN_统一==*模型)
{
如果(rank==0)printf(“内存模型是MPI_WIN_UNIFIED\n”);
}
其他的
{
如果(rank==0)printf(“内存模型是*不是*MPI\u WIN\u统一的\n”);
MPI_Finalize();
返回1;
}
}
//需要为秩0上的表获取有效的本地指针
table=localtable;
if(noderank!=0)
{
MPI\u Win\u共享\u查询(wintable、0、&winsize、&windisp、&table);
}
//现在,所有表指针都应该指向noderank 0上的copy
//使用适当的同步初始化秩0上的表
MPI_Win_围栏(0,wintable);
if(noderank==0)
{
对于(i=0;i
以下是跨两个节点的6个进程的一些示例输出:

Version 3, subversion 1
Library <SGI MPT 2.14  04/05/16 03:53:22>
Rank 3 of 6, rank 0 of 3 in node <r1i0n1>, localtablesize 5
Rank 4 of 6, rank 1 of 3 in node <r1i0n1>, localtablesize 0
Rank 5 of 6, rank 2 of 3 in node <r1i0n1>, localtablesize 0
Rank 0 of 6, rank 0 of 3 in node <r1i0n0>, localtablesize 5
Rank 1 of 6, rank 1 of 3 in node <r1i0n0>, localtablesize 0
Rank 2 of 6, rank 2 of 3 in node <r1i0n0>, localtablesize 0
Memory model is MPI_WIN_UNIFIED
rank 3, noderank 0, table[0] = 15
rank 3, noderank 0, table[1] = 16
rank 3, noderank 0, table[2] = 17
rank 3, noderank 0, table[3] = 18
rank 3, noderank 0, table[4] = 19
rank 4, noderank 1, table[0] = 15
rank 4, noderank 1, table[1] = 16
rank 4, noderank 1, table[2] = 17
rank 4, noderank 1, table[3] = 18
rank 4, noderank 1, table[4] = 19
rank 5, noderank 2, table[0] = 15
rank 5, noderank 2, table[1] = 16
rank 5, noderank 2, table[2] = 17
rank 5, noderank 2, table[3] = 18
rank 5, noderank 2, table[4] = 19
rank 0, noderank 0, table[0] = 0
rank 0, noderank 0, table[1] = 1
rank 0, noderank 0, table[2] = 2
rank 0, noderank 0, table[3] = 3
rank 0, noderank 0, table[4] = 4
rank 1, noderank 1, table[0] = 0
rank 1, noderank 1, table[1] = 1
rank 1, noderank 1, table[2] = 2
rank 1, noderank 1, table[3] = 3
rank 1, noderank 1, table[4] = 4
rank 2, noderank 2, table[0] = 0
rank 2, noderank 2, table[1] = 1
rank 2, noderank 2, table[2] = 2
rank 2, noderank 2, table[3] = 3
rank 2, noderank 2, table[4] = 4
Version 3,subversion 1
图书馆
节点中的秩3/6,秩0/3,localtablesize 5
节点中的第4列(共6列)、第1列(共3列),localtablesize 0
节点中的第5列(共6列)、第2列(共3列),localtablesize 0
节点中的秩0(共6个),秩0(共3个),localtablesize 5
节点中的秩1(共6个),秩1(共3个),localtablesize 0
节点中的秩2/6,秩2/3,localtablesize 0
内存模型是MPI\u WIN\u统一的
秩3,节点秩0,表[0]=15
秩3,节点秩0,表[1]=16
秩3,节点秩0,表[2]=17
秩3,节点秩0,表[3]=18
秩3,节点秩0,表[4]=19
等级4,节点1,表[0]=15
排名4,节点1,表[1]=16
等级4,节点1,表[2]=17
等级4,节点1,表[3]=18
排名4,节点1,表[4]=19
排名5,节点数2,表[0]=15
排名5,节点数2,表[1]=16
排名5,节点数2,表[2]=17
排名5,节点数2,表[3]=18
排名5,节点数2,表[4]=19
秩0,节点秩0,表[0]=0
秩0,节点秩0,表[1]=1
秩0,节点秩0,表[2]=2
秩0,节点秩0,表[3]=3
秩0,节点秩0,表[4]=4
秩1,节点秩1,表[0]=0
秩1,节点秩1,表[1]=1
秩1,节点秩1,表[2]=2
秩1,节点秩1,表[3]=3
秩1,节点秩1,表[4]=4
秩2,节点秩2,表[0]=0
秩2,节点数2,表[1]=1
秩2,节点数2,表[2]=2
秩2,节点数2,表[3]=3
秩2,节点数2,表[4]=4
Version 3, subversion 1
Library <SGI MPT 2.14  04/05/16 03:53:22>
Rank 3 of 6, rank 0 of 3 in node <r1i0n1>, localtablesize 5
Rank 4 of 6, rank 1 of 3 in node <r1i0n1>, localtablesize 0
Rank 5 of 6, rank 2 of 3 in node <r1i0n1>, localtablesize 0
Rank 0 of 6, rank 0 of 3 in node <r1i0n0>, localtablesize 5
Rank 1 of 6, rank 1 of 3 in node <r1i0n0>, localtablesize 0
Rank 2 of 6, rank 2 of 3 in node <r1i0n0>, localtablesize 0
Memory model is MPI_WIN_UNIFIED
rank 3, noderank 0, table[0] = 15
rank 3, noderank 0, table[1] = 16
rank 3, noderank 0, table[2] = 17
rank 3, noderank 0, table[3] = 18
rank 3, noderank 0, table[4] = 19
rank 4, noderank 1, table[0] = 15
rank 4, noderank 1, table[1] = 16
rank 4, noderank 1, table[2] = 17
rank 4, noderank 1, table[3] = 18
rank 4, noderank 1, table[4] = 19
rank 5, noderank 2, table[0] = 15
rank 5, noderank 2, table[1] = 16
rank 5, noderank 2, table[2] = 17
rank 5, noderank 2, table[3] = 18
rank 5, noderank 2, table[4] = 19
rank 0, noderank 0, table[0] = 0
rank 0, noderank 0, table[1] = 1
rank 0, noderank 0, table[2] = 2
rank 0, noderank 0, table[3] = 3
rank 0, noderank 0, table[4] = 4
rank 1, noderank 1, table[0] = 0
rank 1, noderank 1, table[1] = 1
rank 1, noderank 1, table[2] = 2
rank 1, noderank 1, table[3] = 3
rank 1, noderank 1, table[4] = 4
rank 2, noderank 2, table[0] = 0
rank 2, noderank 2, table[1] = 1
rank 2, noderank 2, table[2] = 2
rank 2, noderank 2, table[3] = 3
rank 2, noderank 2, table[4] = 4