如何使MPI_Send让处理器按顺序而不是随机发送
how to make MPI_Send have processors send in order instead of randomly?
我正在尝试运行下面使用并行编程的程序。如果我们使用 4 个处理器,我希望它们包含总和 1+2=3、3+4=7、11 和 15。所以我希望求和向量按这个顺序包含 3、7、11 和 15。HOwever,由于MPI_Send处理器以随机顺序发送,所以我不会对向量求和以包含 7、15、3、11。如何修改下面的代码以确保这一点?
#include<iostream>
#include<mpi.h>
using namespace std;
int main(int argc, char *argv[]){
int mynode, totalnodes;
int sum,startval,endval,accum;
MPI_Status status;
int master=3;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD, &totalnodes); // get totalnodes
MPI_Comm_rank(MPI_COMM_WORLD, &mynode); // get mynode
sum = 0; // zero sum for accumulation
vector <int> sumvector;
startval = 8*mynode/totalnodes+1;
endval = 8*(mynode+1)/totalnodes;
for(int i=startval;i<=endval;i=i+1)
sum=sum+i;
sumvector.push_back(sum);
if(mynode!=master)
{
MPI_Send(&sum,1,MPI_INT,master,1,MPI_COMM_WORLD); //#9, p.92
}
else
{
for(int j=0;j<totalnodes;j=j+1){
if (j!=master)
{
MPI_Recv(&accum,1,MPI_INT,j,1,MPI_COMM_WORLD, &status);
printf("processor %d received from %dn",mynode, j);
sum = sum + accum;
}
}
}
我使用多线程而不是 MPI 更好吗?
我不确定你想做什么,但你当前的代码是等效的(没有打印从哪个等级收到的数字)到下面的代码:
for(int i=startval;i<=endval;i=i+1)
sum=sum+i;
sumvector.push_back(sum);
MPI_Reduce(mynode == master ? MPI_IN_PLACE : &sum, &sum, 1, MPI_INT,
master, MPI_COMM_WORLD);
您正在寻找的是以下之一(结果仅由主等级收集):
for(int i=startval;i<=endval;i=i+1)
sum=sum+i;
sumvector.resize(totalnodes);
MPI_Gather(&sum, 1, MPI_INT, &sumvector[0], 1, MPI_INT,
master, MPI_COMM_WORLD);
或者这个(结果收集到所有等级):
for(int i=startval;i<=endval;i=i+1)
sum=sum+i;
sumvector.resize(totalnodes);
MPI_Allgather(&sum, 1, MPI_INT, &sumvector[0], 1, MPI_INT, MPI_COMM_WORLD);
此外,以下陈述是完全错误的:
HOwever,由于MPI_Send处理器以随机顺序发送,所以我不会对向量求和以包含 7、15、3、11。
MPI点对点通信需要两件事才能成功:必须有一个执行MPI_Send
的发送方和一个执行匹配MPI_Recv
的接收方。消息接收顺序可以通过简单地在循环中调用MPI_Recv
来强制执行,并增加源秩,就像您显示的代码中一样。
有许多
方法可以更简单地执行此操作。首先,您可以将值"收集"到主进程上的向量中:
std::vector <int> sumvector, recvcounts, displs;
startval = 8*mynode/totalnodes+1;
endval = 8*(mynode+1)/totalnodes;
for (int i=0; i<totalnodes; i++)
{
sumvector.push_back(0);
recvcounts.push_back(1);
displs.push_back(i);
}
int myval = startval + endval;
MPI_Gatherv(&myval,
1,
MPI_INTEGER,
&sumvector[0],
&recvcounts[0],
&displs[0],
MPI_INTEGER,
master,
MPI_COMM_WORLD);
这导致求和向量包含:
node 0: (0, 0, 0, 0)
node 1: (0, 0, 0, 0)
node 2: (0, 0, 0, 0)
node 3: (3, 7, 11, 15)
您也可以考虑MPI_Allreduce。该过程将如下所示:
将所有向量元素初始化为 0,
for (int i=0; i<totalnodes; i++)
{
sumvector.push_back(0);
}
并将Mynode的条目修改为您想要的值,
sumvector[mynode] = startval + endval;
在MPI_Allreduce之前,求和向量包含:
node 0: (3, 0, 0, 0)
node 1: (0, 7, 0, 0)
node 2: (0, 0, 11, 0)
node 3: (0, 0, 0, 15)
现在,当您对每个节点上的所有数组求和时,
MPI_Allreduce(MPI_IN_PLACE,
&sumvector[0],
totalnodes,
MPI_INTEGER,
MPI_SUM,
MPI_COMM_WORLD);
它导致求和向量包含:
node 0: (3, 7, 11, 15)
node 1: (3, 7, 11, 15)
node 2: (3, 7, 11, 15)
node 3: (3, 7, 11, 15)
在每个节点上。
相关文章:
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- CMake-按正确顺序将项目与C运行时对象文件链接
- 函数调用中参数的顺序重要吗
- 为什么 Serial.println(<char[]>);返回随机字符?
- 以随机可重现的顺序生成非重复字节的快速方法
- C/C++ Windows 或 Linux 将随机内存块映射成连续的顺序
- 从容器中获取随机元素,该容器在恒定时间内没有严格的元素顺序
- 编译时随机化结构成员的顺序
- 如何使用 std::shuffle 以随机顺序对具有唯一指针的向量进行洗牌
- 随机顺序的连续数字
- OMP并行以随机顺序写入
- 如何使MPI_Send让处理器按顺序而不是随机发送
- 使用提升 Qi 解析为结构的随机顺序
- 如何从向量中删除随机元素而不重复它们并保持元素顺序?C++
- 以随机顺序接收行时压缩位矩阵
- 以随机顺序迭代数组
- 如何使用双向搜索按字母顺序将随机字符串添加到数组中
- 随机顺序洗牌cv::Mat在OpenCV中
- 每次读/写有多少次随机/顺序访问
- 在c++中以随机顺序显示5个图像