【问题标题】:Using MPI_Send and MPI_Recv instead of MPI_Gather使用 MPI_Send 和 MPI_Recv 而不是 MPI_Gather
【发布时间】:2021-03-11 06:43:02
【问题描述】:

我想比较 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

有什么办法吗?

【问题讨论】:

    标签: c++ performance parallel-processing mpi hpc


    【解决方案1】:

    问题在于:

    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]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-11
      • 2015-05-14
      • 2014-04-17
      • 2011-01-24
      • 1970-01-01
      • 2017-10-25
      • 1970-01-01
      • 2016-04-22
      相关资源
      最近更新 更多