MPI库和内存

时间:2016-02-13 15:38:00

标签: c memory mpi

我在理解工作共享内存方面遇到了一些问题。有一个主要过程和另外N个。主进程将数据发送给其他人,我就这样做了(数据放在shared_mem [i] for i进程中):

int *shared_mem = calloc(numb_of_parts, sizeof(double));
if(world_rank == 0)
{
    for(int i = 1; i < numb_of_parts; i++)
    {
        MPI_Send(shared_mem+i, 1, MPI_DOUBLE, i, 0, MPI_COMM_WORLD);
    }
}

下一个进程计算内容并在同一个单元格中写入数据:

{
    MPI_Recv(shared_mem+world_rank, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    /* do smth with shared_mem[i] */
    MPI_Send(shared_mem+world_rank, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
}

然后我等待所有进程并想要计算主进程中所有单元格(使用新数据)的总和:

PI_Barrier(MPI_COMM_WORLD);
if(world_rank == 0)
{
    for(int i = 0; i < numb_of_parts; i++)
    {
        sum += shared_mem[i];
    }
}

但结果我总是得到以前数据的总和,即在主进程数组中没有改变。怎么了?

1 个答案:

答案 0 :(得分:0)

您可以尝试取消double *shared_mem = calloc(numb_of_parts, sizeof(double));吗?目前,它被删除为int*,因此shared_mem[i]shared_mem+i可能与预期的不同,因为int的大小可能与大小double

此外,MPI还有一些功能可以帮助您:

  • 可以合并使用MPI_SUM的{​​{3}}和MPI_Scatter()功能。
  • 您可以使用MPI_Reduce()在给定通信器中的进程之间分配共享内存,如果可能的话。

@Gilles是对的:进程之间不共享缓冲区mem_shared。实际上,每个进程都分配自己的缓冲区mem_shared,这就是为什么需要传递消息的原因。

以下是基于代码段的工作代码。我不得不为根进程添加接收参数。是缺少什么?使用mpicc main.c -o main -sdt=c99进行编译,然后按mpirun -np 4 main运行。

/* -*- Mode: C; c-basic-offset:4 ; -*- */
/*
 *  (C) 2001 by Argonne National Laboratory.
 *      See COPYRIGHT in top-level directory.
 */

/* This is an interactive version of cpi */
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int main(int argc,char *argv[])
{

    int  numb_of_parts, rank;
    MPI_Init(&argc,&argv);
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);
    MPI_Comm_size(MPI_COMM_WORLD,&numb_of_parts);    


    int *mem = calloc(numb_of_parts, sizeof(double));
    if(rank == 0)
    {
        mem[0]=0;
        for(int i = 1; i < numb_of_parts; i++)
        {
            mem[i]=i;
            MPI_Send(mem+i, 1, MPI_DOUBLE, i, 0, MPI_COMM_WORLD);


        }
        for(int i = 1; i < numb_of_parts; i++)
        {
            MPI_Recv(mem+i, 1, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        }

    }else{
        MPI_Recv(mem+rank, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        /* do smth with shared_mem[i] */
        mem[rank]=mem[rank]*2;
        MPI_Send(mem+rank, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
    }



    MPI_Barrier(MPI_COMM_WORLD);
    double sum=0;
    if(rank == 0)
    {
        for(int i = 0; i < numb_of_parts; i++)
        {
            sum += mem[i];
        }

        printf("sum is %g\n",sum);
    }

    MPI_Finalize();
    return 0;
}

问题可能出在/* do smth with shared_mem[i] */ ...如果它什么都不做,或者它没有修改mem[rank]