使用 MPI_Send 和 MPI_Recv 而不是 MPI_Gather
Using MPI_Send and MPI_Recv instead of MPI_Gather
我想比较MPI_Send和MPI_recv与MPI_Gather的性能差异;所以我试图在没有 MPI_Gather 的情况下从这段代码中得到答案,但问题是 root 的缓冲区似乎没有更新。代码是:
#include <fstream>
#include <iostream>
#include <vector>
#include <string>
#include "mpi.h"
using namespace std;
const int N = 2;
int main() {
MPI_Init(NULL, NULL);
int rank;
int size;
int root = 0;
vector<int> x(N);
vector<int> receive_data(N);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
const int leng = size * N;
vector<int> single_arr(leng);
for (int i = 0; i < N;i++) {
x[i] = rank + i;
}
if (rank == 0) {
for (int i = 0; i < N; i++) {
single_arr[i] = x[i];
}
}
if (rank != root) {
MPI_Send(x.data(), N, MPI_INT, 0, 0, MPI_COMM_WORLD);
}
if (rank == root) {
for (int i = 1; i < size; i++) {
MPI_Recv(single_arr.data(), N, MPI_INT, rank + i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
}
if (rank == root) {
for (int i = 0; i < single_arr.size();i++) {
cout << i << "\t" << single_arr[i] << endl;
}
}
MPI_Finalize();
}
结果是:
0 3
1 4
2 0
3 0
4 0
5 0
6 0
7 0
但是,我想要这个:
0 0
1 1
2 1
3 2
4 2
5 3
6 3
7 4
有什么办法吗?
问题在于:
if (rank != root) {
MPI_Send(x.data(), N, MPI_INT, 0, 0, MPI_COMM_WORLD);
}
每个进程都会将x
数组的N个元素发送给进程=0,
然后处理 0 :
if (rank == root) {
for (int i = 1; i < size; i++) {
MPI_Recv(single_arr.data(), N, MPI_INT, rank + i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
}
将从每个进程接收该数据,但是它将覆盖(而不是追加)数组single_arr
.
的值
这就是为什么在
if (rank == root) {
for (int i = 0; i < single_arr.size();i++) {
cout << i << "\t" << single_arr[i] << endl;
}
}
您打印最后一个进程的值(即 3 和 4),后跟零。
要修复它,您必须执行以下操作:
if (rank == root) {
for (int i = 1; i < size; i++) {
MPI_Recv(&(single_arr.data()[N * i]), N, MPI_INT, rank + i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
}
接收数据到数组single_arr
从[N * i]
到[N * i + N]
的位置
我想比较MPI_Send和MPI_recv与MPI_Gather的性能差异;所以我试图在没有 MPI_Gather 的情况下从这段代码中得到答案,但问题是 root 的缓冲区似乎没有更新。代码是:
#include <fstream>
#include <iostream>
#include <vector>
#include <string>
#include "mpi.h"
using namespace std;
const int N = 2;
int main() {
MPI_Init(NULL, NULL);
int rank;
int size;
int root = 0;
vector<int> x(N);
vector<int> receive_data(N);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
const int leng = size * N;
vector<int> single_arr(leng);
for (int i = 0; i < N;i++) {
x[i] = rank + i;
}
if (rank == 0) {
for (int i = 0; i < N; i++) {
single_arr[i] = x[i];
}
}
if (rank != root) {
MPI_Send(x.data(), N, MPI_INT, 0, 0, MPI_COMM_WORLD);
}
if (rank == root) {
for (int i = 1; i < size; i++) {
MPI_Recv(single_arr.data(), N, MPI_INT, rank + i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
}
if (rank == root) {
for (int i = 0; i < single_arr.size();i++) {
cout << i << "\t" << single_arr[i] << endl;
}
}
MPI_Finalize();
}
结果是:
0 3
1 4
2 0
3 0
4 0
5 0
6 0
7 0
但是,我想要这个:
0 0
1 1
2 1
3 2
4 2
5 3
6 3
7 4
有什么办法吗?
问题在于:
if (rank != root) {
MPI_Send(x.data(), N, MPI_INT, 0, 0, MPI_COMM_WORLD);
}
每个进程都会将x
数组的N个元素发送给进程=0,
然后处理 0 :
if (rank == root) {
for (int i = 1; i < size; i++) {
MPI_Recv(single_arr.data(), N, MPI_INT, rank + i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
}
将从每个进程接收该数据,但是它将覆盖(而不是追加)数组single_arr
.
这就是为什么在
if (rank == root) {
for (int i = 0; i < single_arr.size();i++) {
cout << i << "\t" << single_arr[i] << endl;
}
}
您打印最后一个进程的值(即 3 和 4),后跟零。
要修复它,您必须执行以下操作:
if (rank == root) {
for (int i = 1; i < size; i++) {
MPI_Recv(&(single_arr.data()[N * i]), N, MPI_INT, rank + i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
}
接收数据到数组single_arr
从[N * i]
到[N * i + N]