【问题标题】:MPI: load balancing algorithm (Master-Slave model)MPI:负载均衡算法(主从模型)
【发布时间】:2016-09-11 07:16:27
【问题描述】:

我正在使用 MPI 来并行化循环 [0,ma​​x]。我想要一个主进程(假设进程 0)最初将该循环划分为一组 n 任务(n 次迭代),然后逐步影响一组任务到 x每当完成其先前的工作(先前的一组任务)时,从属进程。换句话说,我想使用 MPI 的阻塞和/或非阻塞发送/接收实现负载平衡算法,但不知道如何继续。另外,有没有办法在“max”和“x”的函数中找到一组任务(n参数)的最佳大小?

非常感谢您的帮助。

【问题讨论】:

  • 我会伸出脖子,因为没有人回答你 8 小时,并说人们不倾向于使用 MPI 进行负载平衡,只是为了将问题拆分为已知的网格/层。您将不得不考虑 I/O 需求,以及诸如一个或多个 MPI 节点发生故障并挂起整个应用程序之类的事情。
  • @MarkSetchell 您好,感谢您的回复。老实说,在针对我的问题进行研究时,我发现了很多文章,关于使用 MPI 提高分布式平台(尤其是异构平台)的性能的不同负载平衡方法(工作共享、工作窃取……),例如集群。所以我认为使用消息传递接口进行负载均衡并不稀奇。
  • 我不想争论,而且,就我而言,每个人都应该使用让他们快乐并能最好地使用的工具。我只想说我的想法更符合这篇文章dursi.ca/hpc-is-dying-and-mpi-is-killing-it

标签: algorithm performance mpi load-balancing


【解决方案1】:

我终于从here 中找到了以下代码,它基本上是基于 MPI 主/从模型的动态负载平衡框架,正是我想要的。不过,我仍然看不到如何以最佳方式划分初始工作集。

#include <mpi.h>
#define WORKTAG     1
#define DIETAG     2
main(argc, argv)
int argc;
char *argv[];
{
    int         myrank;
    MPI_Init(&argc, &argv);   /* initialize MPI */
    MPI_Comm_rank(
    MPI_COMM_WORLD,   /* always use this */
    &myrank);      /* process rank, 0 thru N-1 */
    if (myrank == 0) {
        master();
    } else {
        slave();
    }
    MPI_Finalize();       /* cleanup MPI */
}

master()
{
    int ntasks, rank, work;
    double       result;
    MPI_Status     status;
    MPI_Comm_size(
    MPI_COMM_WORLD,   /* always use this */
    &ntasks);          /* #processes in application */
/*
* Seed the slaves.
*/
    for (rank = 1; rank < ntasks; ++rank) {
        work = /* get_next_work_request */;
        MPI_Send(&work,         /* message buffer */
        1,              /* one data item */
        MPI_INT,        /* data item is an integer */
        rank,           /* destination process rank */
        WORKTAG,        /* user chosen message tag */
        MPI_COMM_WORLD);/* always use this */
    }

/*
* Receive a result from any slave and dispatch a new work
* request work requests have been exhausted.
*/
    work = /* get_next_work_request */;
    while (/* valid new work request */) {
        MPI_Recv(&result,       /* message buffer */
        1,              /* one data item */
        MPI_DOUBLE,     /* of type double real */
        MPI_ANY_SOURCE, /* receive from any sender */
        MPI_ANY_TAG,    /* any type of message */
        MPI_COMM_WORLD, /* always use this */
        &status);       /* received message info */
        MPI_Send(&work, 1, MPI_INT, status.MPI_SOURCE,
        WORKTAG, MPI_COMM_WORLD);
        work = /* get_next_work_request */;
    }
/*
* Receive results for outstanding work requests.
*/
    for (rank = 1; rank < ntasks; ++rank) {
        MPI_Recv(&result, 1, MPI_DOUBLE, MPI_ANY_SOURCE,
        MPI_ANY_TAG, MPI_COMM_WORLD, &status);
    }
/*
* Tell all the slaves to exit.
*/
    for (rank = 1; rank < ntasks; ++rank) {
        MPI_Send(0, 0, MPI_INT, rank, DIETAG, MPI_COMM_WORLD);
    }
}

slave()
{
    double              result;
    int                 work;
    MPI_Status          status;
    for (;;) {
        MPI_Recv(&work, 1, MPI_INT, 0, MPI_ANY_TAG,
        MPI_COMM_WORLD, &status);
/*
* Check the tag of the received message.
*/
        if (status.MPI_TAG == DIETAG) {
            return;
        }
        result = /* do the work */;
        MPI_Send(&result, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-26
    • 2015-08-19
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    • 2016-11-12
    相关资源
    最近更新 更多