在 MPI 中使用循环
Using Loops in MPI
我正在尝试通过反转和在 C 上使用 MPI 编码来对大型数组进行排序。
基本上,我的程序将数组拆分为工作线程的部分,每个工作线程找到自己的递增和递减条带,并将条带发送回根目录。Root 通过查找和使用这些条带的最大和最小元素来进行一些反转。当没有剩余断点时,程序结束,这意味着数组已排序。
这是一个很长的代码,所以我简化了我的问题:
int *ARRAY;
int main(int argc, char *argv[])
{
int p_id, n_procs, flag = 1;
MPI_Init(&argc, &argv);
MPI_Status status;
MPI_Comm_rank(MPI_COMM_WORLD, &p_id);
MPI_Comm_size(MPI_COMM_WORLD, &n_procs);
if(p_id == 0) {
ARRAY = createRandomArray(N_DATA);
// PRINT UNSORTED ARRAY
while(hasBreakPoints(ARRAY, N_DATA)) {
for(i=1;i<n_procs; i++)
// SEND PORTIONS TO WORKERS
for(i=1;i<n_procs; i++)
// RECEIVE EACH STRIP FROM WORKERS
// FIND MAX AND MIN OF STRIPS
// MAKE REVERSALS ON "ARRAY"
}
flag = 0;
// PRINT SORTED ARRAY
}
else {
while(flag == 1) {
// RECEIVE PORTION FROM ROOT
// FIND MY OWN STRIPS
// SEND MY OWN STRIPS TO ROOT
}
}
MPI_Finalize();
return 0;
}
如您所见,我需要使用 while
循环来运行程序,直到没有断点。我知道MPI_Send
命令的数量必须等于MPI_Receive
命令的数量。因此,我只是创建了一个标志来运行ROOT
和WORKERS
相同的时间。
通过使用这种懒惰的方法,程序可以正常工作,但永远不会结束,也不会进入MPI_Finalize
。是否有任何关于这种或更有效的使用方式的修复?感谢您的帮助。
你的flag
变量是每个进程的局部变量,你必须找到一种方法,当它发生变化时,将其值从进程#0转移到其他进程。
实际上,您可以通过例如使用消息标签来解决此问题。您的工作进程可以使用MPI_ANY_TAG
从根接收,并决定下一步要做什么,即发回数据或刚刚完成,具体取决于收到的实际标记值。这可能看起来像这样(未测试):
int *ARRAY;
int main(int argc, char *argv[])
{
int p_id, n_procs, flag = 1;
MPI_Init(&argc, &argv);
MPI_Status status;
MPI_Comm_rank(MPI_COMM_WORLD, &p_id);
MPI_Comm_size(MPI_COMM_WORLD, &n_procs);
const int COMPUTE=1, STOP=2;
if(p_id == 0) {
ARRAY = createRandomArray(N_DATA);
// PRINT UNSORTED ARRAY
while(hasBreakPoints(ARRAY, N_DATA)) {
for(i=1;i<n_procs; i++)
// SEND PORTIONS TO WORKERS using tag COMPUTE
MPI_Send(......, COMPUTE, ...);
for(i=1;i<n_procs; i++)
// RECEIVE EACH STRIP FROM WORKERS
// FIND MAX AND MIN OF STRIPS
// MAKE REVERSALS ON "ARRAY"
}
// send the STOP message using tag STOP
for(i=1;i<n_procs; i++)
MPI_Send(...., STOP, ...);
// PRINT SORTED ARRAY
}
else {
while(flag == 1) {
// RECEIVE PORTION FROM ROOT using MPI_ANY_TAG
MPI_Recv(..., MPI_ANY_TAG, ..., &status);
if ( status.MPI_TAG == COMPUTE ) {
// FIND MY OWN STRIPS
// SEND MY OWN STRIPS TO ROOT
}
else
flag = 0;
}
}
MPI_Finalize();
return 0;
}
正如Gilles指出的那样,flag不能用于我的程序。我通过检查数组是否在ROOT
和WORKER
部分都排序来解决问题。为此,我必须将ARRAY
传递给ROOT
的工人。而且,可以选择地将ARRAY
保留在工人部分中作为LOCAL
.
int *ARRAY;
int main(int argc, char *argv[])
{
int p_id, n_procs;
MPI_Init(&argc, &argv);
MPI_Status status;
MPI_Comm_rank(MPI_COMM_WORLD, &p_id);
MPI_Comm_size(MPI_COMM_WORLD, &n_procs);
if(p_id == 0) {
ARRAY = createRandomArray(N_DATA);
// PRINT UNSORTED ARRAY
while(hasBreakPoints(ARRAY, N_DATA)) {
for(i=1;i<n_procs; i++)
// SEND WHOLE ARRAY TO ALL WORKERS
for(i=1;i<n_procs; i++)
// SEND PORTIONS TO WORKERS
for(i=1;i<n_procs; i++)
// RECEIVE EACH STRIP FROM WORKERS
// FIND MAX AND MIN OF STRIPS
// MAKE REVERSALS ON "ARRAY"
}
// PRINT SORTED ARRAY
}
else {
int *LOCAL;
// RECEIVE ARRAY TO LOCAL
while(hasBreakPoints(LOCAL, N_DATA) {
// RECEIVE PORTION FROM ROOT
// FIND MY OWN STRIPS
// SEND MY OWN STRIPS TO ROOT
}
}
MPI_Finalize();
return 0;
}
虽然我不明白怎么做,但这解决了我的问题。我仍然愿意听取您的意见。谢谢。
相关文章:
- 如何循环打印顶点结构
- 如何在C++中从两个单独的for循环中添加两个数组
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 正在尝试了解输入验证循环
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 循环后如何继续阅读
- Ardunio UNO解决了多个重叠的定时器循环
- Eigen如何在容器循环中干净地附加矩阵
- 在某些循环内使用vector.push_back时出现分段错误
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- 为什么我的for循环不能正确获取argv
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- while循环中while循环的时间复杂度是多少
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- 为什么在这个代码结束循环中没有得到结束
- 使用 MPI 的 C++ 中的并行 for 循环
- 如何在 C++ 中使用 MPI 对简单循环进行负载平衡
- 在 MPI 中使用循环
- MPI将嵌套循环中的变量写入单个文件
- MPI多个发送和接收在循环中