我对并行处理还很陌生。我有一个以顺序方式计算和存储二维数组元素的示例。我想使用 MPI 将其转换为并行程序。
以下是顺序程序的代码。
#include <stdio.h>
int x,y,xMax=10,yMax=10;
int main ()
{
int arr[yMax][xMax];
for(y =0; y<yMax;x++)
{
for (x=0;x<xMax;x++)
{
arr[y][x]=x+y;
printf("%d",arr[y][x]);
}
printf("\n");
}
}
我尝试通过并行化外部 for 循环将其转换为等效的 MPI 程序,如下所示: 在这里,我希望每个进程计算每个数组行的值并将输出数组发送到根进程,根进程最后将收集所有数组并将它们组合成单个二维数组。
#include <stdio.h>
#include <mpi.h>
int x,y,xMax=10,yMax=10,size,rank;
int main()
{
int arr[xMax];
int arrall[yMax][xMax];
MPI_Init(NULL,NULL);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
for(y =0+rank; y<yMax;y=y+size)
{
for (x=0;y<xMax;x++)
{
arr[y][x]=x+y;
}
MPI_Send(arr,xMax,MPI_INT,0,0,MPI_COMM_WORLD);
}
if(rank==0)
{
MPI_Gather(arr,xMax,MPI_INT,&arrall,xMax*yMax,MPI_INT,0,MPI_COMM_WORLD);
}
MPI_Finalize();
}
但是当我编译程序并等待很长一段时间时,它仍然没有给出任何结果。并且它不显示错误。 我已经尝试了相当长一段时间并搜索了任何解决方案但无法找到。任何帮助都感激不尽。谢谢
最佳答案
其实你想得太复杂了。 MPI 中的集体操作负责发送和接收部分。当标记写入时,点对点消息(例如MPI_Send
)将仅与点对点消息(例如MPI_Recv
)匹配,而集合仅与相同的集合匹配。
整个通信是通过对所有进程的 MPI_Gather
的一次调用来完成的:
MPI_Gather(arr,xMax,MPI_INT,arrall,xMax,MPI_INT,0,MPI_COMM_WORLD);
请注意,recvcount
为 xMax
,因为它指定每次接收中的元素数量。
更多评论:
- 您必须确保
size == yMax
- 这只有效,因为二维数组在内存中按行连续排列。这不适用于指针“2D”数组。
- 在真正的 MPI 程序中,您希望避免在单个等级上收集整个工作数据,因为它会限制可扩展性。相反,你应该做所有分布式的事情。
编辑:每个等级多行的一种特定方法:
int rows_per_rank = yMax / size;
assert(rows_per_rank * size == yMax);
MPI_Gather(arr,xMax * rows_per_rank,MPI_INT,arrall,xMax * rows_per_rank,MPI_INT,0,MPI_COMM_WORLD);
关于c - 使用并行处理 MPI 迭代 2D 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41888894/