c - 为什么这两个 MPI 发送的行为不同?

标签 c mpi

我在 MPI 进程之间有一个类似于模式通信的管道。其中进程将消息作为管道阶段相互发送。 以下示例显示了以这种模式进行通信的三个进程。

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

    //declare stage function
    void* testcall(void* d);

    int main(int args, char** argv){
        int rank, size;
        MPI_Status status;
        MPI_Init(&args,&argv);
        MPI_Comm_rank(MPI_COMM_WORLD,&rank);
        MPI_Comm_size(MPI_COMM_WORLD,&size);

        if(rank==0){ 
            int k;  
            int x[3] = {10,11,12};
            void* data = malloc(sizeof(int));             
            for( k=0 ; k< 3;k++){           
                data = &x[k];           
                MPI_Send(data,4,MPI_BYTE,1,0,MPI_COMM_WORLD);   
            }
        }

        if(rank==1){                                
            void* rcv = malloc(sizeof(int));
            void* snd = malloc(sizeof(int));
            int k;
            for( k=0 ; k< 3;k++){
                MPI_Recv(rcv,4,MPI_BYTE,0,0,MPI_COMM_WORLD,&status);              
                snd = testcall(rcv);                        
                int z = *(int *) snd;  
                printf("RCV 1: %d \n",z);
                MPI_Send(&snd,4,MPI_BYTE,2,0,MPI_COMM_WORLD);
            }
        }

        if(rank==2){
            void* rcv2 = malloc(sizeof(int));
            void* snd2 = malloc(sizeof(int));
            int k;
            for( k=0 ; k< 3;k++){
                MPI_Recv(rcv2,4,MPI_BYTE,1,0,MPI_COMM_WORLD,&status);
                snd2 = testcall(rcv2);
                int z = *(int *) snd2;
                printf("RCV 2: %d \n",z);
            }
        }

        MPI_Finalize();
        return 0;
    }

    void* testcall(void* d){
        int z = *(int *) d;
        int k = z * 2;
        void* rslt = malloc(sizeof(int));
        rslt = &k;
        return rslt;
    }

输出:

RCV1:20

RCV1:22

RCV1:24

收件人:2136566600

收件人:2136566600

收件人:2136566600

不过我的代码有一个问题。从进程 0 发送到进程 1 成功并在我打印时给我正确的。

虽然从进程 1 发送到进程 2 似乎成功了,但当我尝试打印时,它只是一个意外的数字(如上面的输出所示)。

我不明白为什么这两个发送行为不同。 (两者都发送一个由 void 指针指向的值。为什么第二次发送是错误的)??

请帮忙。

最佳答案

void* testcall(void* d){
    int z = *(int *) d;
    int k = z * 2;
    void* rslt = malloc(sizeof(int));
    rslt = &k;
    return rslt;
}

这段代码没有达到您的预期。 rslt = &k; 行用 k 的地址覆盖了 rslt 指针的值(您在其他几个语句中也这样做)。首先,这会导致内存泄漏,因为由 malloc 分配的内存区域地址丢失了。其次,k 是一个自动(堆栈)变量,一旦 testcall 返回,其位置将用于其他目的。它仅适用于您的情况,因为 testcall()int z = *(int *) snd; 之间不存在其他函数调用。正确的函数应该是:

void* testcall(void* d){
    int z = *(int *) d;
    int k = z * 2;
    int* rslt = malloc(sizeof(int));
    *rslt = k;
    return rslt;
}

然后这一行来自排名 1 的代码:

MPI_Send(&snd,4,MPI_BYTE,2,0,MPI_COMM_WORLD);

snd 本身就是一个指针。您正在发送指针的地址,这就是等级 2 打印奇怪值的原因。正确的说法应该是:

MPI_Send(snd,4,MPI_BYTE,2,0,MPI_COMM_WORLD);

输出:

RCV 1: 20
RCV 1: 22
RCV 1: 24
RCV 2: 40
RCV 2: 44
RCV 2: 48

关于c - 为什么这两个 MPI 发送的行为不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12662991/

相关文章:

c - fread 和 endianness : will fread(pointer, sizeof(some),1,file pointer) 有相同的结果吗?

c++ - Mac OSX 上的 c/c++ clang 链接错误 - webkitgtk

c - 具有包含动态分配数组的自定义数据类型的 MPI_reduce() : segmentation fault

language-agnostic - 并行代码文档的哪种图表?

c - MPI:处理器在单个 MPI 进程上无法达到 100%

c - 奇怪的段错误发生

c - scanf() 和 fscanf() 有什么区别?

c - 给定一个指向结构的指针,我可以在一行中将聚合初始化器的结果分配给结构吗?

parallel-processing - 何时不使用 MPI

mpi - 发送多个mpi非阻塞发送-它会保留发送的顺序吗