两个处理器之间的通信(并行编程)

时间:2015-10-24 22:53:59

标签: c parallel-processing mpi communication

我想写一个代码: P0处理器从键盘获取一个数组,并将该数组发送到P1处理器。 P1处理器将所有值打印到屏幕。例如:

[P0]: Enter the size of array: 1
[P0]: Enter the elements of array: 3
[P1]: The array is: 3
[P0]: Enter the size of array: 3
[P0]: Enter the elements of array: 5 7 5
[P1]: The array is: 5 7 5
.
.
.

这是我的第一份工作。我认为有太多的错误。但我是新人。想学习如何编码。

#include <stdio.h>
#include <mpi.h>

#define n 100

int main(int argc, char *argv[]){
    int my_rank, size_cm;
    int value, i;
    int dizi[n];
    double senddata[n];
    double recvdata[n];

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size_cm);

    value=0;

    if(my_rank == 0){
        printf("[%d]: Enter the size of array: ",&my_rank);
        scanf("%d",value);
        printf("[%d]: Enter the elements of array",&my_rank);
        for(i=0; i<n; i++){
            scanf("%d", &dizi[n]);
            senddata[0] = dizi[];
            MPI_Send(senddata, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
        }
    }
    if(my_rank == 1){
        MPI_Recv(recvdata, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,    
        printf("[%d]: The array is: %d ",&my_rank, dizi[n]);
    }
    MPI_Finalize();
    return 0;
}

1 个答案:

答案 0 :(得分:0)

为了获得编译的最小示例,我将缺少的参数添加到MPI_Recv()

MPI_Status status;
MPI_Recv(recvdata, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,&status);

我还修改了senddata[0] = dizi[];senddata[0] = dizi[i];

  • 当我尝试编译您提供的代码时,我收到了警告:
  

格式'%d'需要类型为'int'的参数,但参数2的类型为'int *

函数scanf()需要指向数据的指针来修改它,因此int a;scanf("%d",&a);是正确的。但是printf()只需要数据,因为它不会修改它:int a;printf("%d",a);是正确的方法。

  • 如果要填充数组,请使用scanf("%d", &dizi[i]);,而不是scanf("%d", &dizi[n]);n是数组dizi的长度。因此,索引n不在数组中,因为数组的索引从0开始。这可能会触发未定义的行为(奇怪的值,分段错误甚至是正确的结果!)。
  • 由于在MPI_Send()中调用for(i=0; i<n; i++),因此进程0尝试向进程1发送n消息。但进程1仅接收一个消息。因此,进程0将被锁定在i = 1,等待进程1接收第二消息。这是一个僵局。

我假设您正在尝试将进程0中的数组发送到进程1.以下基于您的代码应该可以解决问题。数组的实际长度为n_arr

#include <stdio.h>
#include <mpi.h>
#include <stdlib.h>

#define n 100

int main(int argc, char *argv[]){
    int my_rank, size_cm;
    int n_arr;
    int i;
    int dizi[n];
    //    double senddata[n];
    //    double recvdata[n];

    MPI_Status status;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size_cm);

    if(my_rank == 0){
        // fflush(stdout); because the standard output is buffered...
        printf("[%d]: Enter the size of array: ",my_rank);fflush(stdout);
        if(scanf("%d",&n_arr)!=1){fprintf(stderr,"input error\n");exit(1);}
        if(n_arr>100){
            fprintf(stderr,"The size of the array is too large\n");exit(1);
        }
        printf("[%d]: Enter the elements of array",my_rank);fflush(stdout);
        for(i=0; i<n_arr; i++){
            if(scanf("%d", &dizi[i])!=1){fprintf(stderr,"input error\n");exit(1);}

        }
        //sending the length of the array
        MPI_Send(&n_arr, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
        //senfing the array
        MPI_Send(dizi, n_arr, MPI_INT, 1, 0, MPI_COMM_WORLD);
    }
    if(my_rank == 1){
        // receiving the length of the array
        MPI_Recv(&n_arr, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,&status);
        //receiving the array 
        MPI_Recv(dizi, n_arr, MPI_INT, 0, 0, MPI_COMM_WORLD,&status);    
        printf("[%d]: The array of size %d is: ",my_rank,n_arr);
        for(i=0; i<n_arr; i++){
            printf("%d ",dizi[i]);
        }
        printf("\n");
    }
    MPI_Finalize();
    return 0;
}

通过运行mpicc main.c -o main并按mpirun -np 2 main

运行来编译

我添加了一些东西来检查输入是否正确(总是一件好事)并处理n_arr大于n = 100的情况。使用malloc()为数组分配内存可以避免最后一个:这部分留给你!