gpt4 book ai didi

c++ - MPI 发送消息或将它们作为参数

转载 作者:行者123 更新时间:2023-11-28 06:56:37 26 4
gpt4 key购买 nike

我有一个由一名经理和多名 worker 组成的 MPI 实现。 main 函数位于名为 run_mpi.cpp 的文件中。它初始化 MPI 并调用 manager.cppworker.cpp。我想在 worker.cpp 中有一些变量。我有两种方法:

  1. main 函数在 run_mpi.cpp 中调用它时,我可以将变量作为参数传递给 worker.cpp

  2. 我可以使用 MPI_SendMPI_Isendmanager.cpp 中发送变量。

我可以在什么情况下使用它们?它们有什么好处?

最佳答案

您需要将两者视为完全独立的程序。 MPI 在程序的实例(等级)之间提供了一个通信层,但它们之间没有共享数据。假设您的 master 读取一个包含数字列表的文件,将这些数字中的每一个发送给一个 worker,然后该 worker 对该数字执行某些操作。你可能会有这样的事情:

float localx;
float *x;
int rank;
int size;

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

x=new float[size];

if (rank==0)
{
/* Typically, rank 0 is considered the master rank in a master/worker setup
Open, read, and close file.
Assume the data is read into array x, which is single precision floating point.
For ease of illustration, I'm sending to one rank at a time, but this
is better accomplished using MPI_Scatter. */
localx=x[0];
for (int i=1; i<size; i++)
{
MPI_Send(&x[i], 1, MPI_FLOAT, i, i, MPI_COMM_WORLD);
}
master(localx); // The master subroutine does whatever it needs to do
} else
{
// If the rank isn't 0, then the rank is a worker
MPI_Recv(&localx, 1, MPI_FLOAT, 0, rank, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
worker(localx);
}

delete[] x;

前三个 MPI 调用将初始化 MPI 通信环境(MPI_Init),获取当前实例的等级数(MPI_Comm_rank)和通信器的大小(MPI_Comm_size)。 MPI_COMM_WORLD 的大小是您使用 mpirun 启动的行数。接下来,x 被分配为每个 worker 保存一个值。

通常,如果您使用主/从模型,等级 0 被视为主等级。因此,如果等级数为 0,我们将继续读取文件。作为旁注,除非您使用 MPI I/O 或其他并行 I/O,否则只有一个级别访问文件会更安全。 master 将读取文件,对于我的示例,每个 worker 等级应该有一个值。正如我在评论中所说,使用 MPI_Scatter 是一种更好的方法,但如果您是 MPI 的新手,我们现在将坚持使用基础知识。首先,我将 localx 设置为 x[0]。然后,我为每个等级调用 MPI_Send 一次,将 x 的一个元素发送到每个等级。一旦数据发送出去,master rank 就可以调用 master(localx) 并在那里做任何需要做的事情。

如果等级号不为0,则等级为 worker 。工作人员不会读取该文件。他们将改为调用 MPI_Recv 来获取从主机发送的数据。 worker 队伍将简单地坐在这里等待数据到达。完成后,worker 将调用 worker(localx) 并在其中执行任何操作。

我见过人们在学习 MPI 时遇到的最大障碍之一是每个级别的内存是分开的。与线程不同,绝对没有共享内存(您的应用程序可以看到,MPI 实现可能会为自己设置一些东西)。通过分配点,没有任何等级为 localx 或 x 设置任何值。高手看完后,只有高手知道x包含的是什么。发送数据后,每个 worker rank 都会有一个来自 master 中存储在 localx 中的 x 的值。

我提到过使用 MPI_Scatter 更好。这是如何完成的。条件 block 前后的所有内容都将保持不变。条件 block 将变为:

if (rank==0)
{
// Read the file, fill x
}
MPI_Scatter(&x[0], size, MPI_FLOAT, &localx, 1, MPI_FLOAT, 0, MPI_COMM_WORLD);
if (rank==0)
{
master(localx);
} else
{
worker(localx);
}

不同之处在于,现在,我们不再为每个 worker 级别发送和接收一次,而是一次性将一个数组分散到每个级别中的变量。根据您的操作,可能无法使用 MPI_Scatter。这个例子很简单,你可以。

关于c++ - MPI 发送消息或将它们作为参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23079173/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com