【问题标题】:MPI library and memoryMPI 库和内存
【发布时间】:2016-02-13 15:38:00
【问题描述】:

我在理解共享内存的工作原理方面存在一些问题。有一个主要过程和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];
    }
}

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

【问题讨论】:

  • 2 条评论:1/ shared_mem 对于一个根本不共享的数组来说是一个非常糟糕的名称,2/ 你声明它 int* 但将它用作 double 所以这会导致问题...
  • 能否提供mcve。请已修复数据类型问题。

标签: c memory mpi


【解决方案1】:

你可以尝试解除double *shared_mem = calloc(numb_of_parts, sizeof(double)); 吗?目前,它被清除为int*,因此shared_mem[i]shared_mem+i 可能不是预期的那样,因为int 的大小可能与double 的大小不同。

此外,MPI 的一些功能可以极大地帮助您:

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

这是基于您的代码 sn-ps 的工作代码。我必须为根进程添加接收标准。是缺少什么吗?使用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]

【讨论】:

  • 我有固定的类型,但还是有同样的问题:(
  • 我太不专心了,我忘记在主进程中接收消息,而主进程中的 ofc 没有任何变化。谢谢!
猜你喜欢
  • 2012-03-05
  • 2012-02-01
  • 2018-08-28
  • 2020-06-29
  • 2010-12-30
  • 1970-01-01
  • 2015-06-09
  • 1970-01-01
相关资源
最近更新 更多