【问题标题】:Unbalanced load (v2.0) using MPI使用 MPI 的不平衡负载 (v2.0)
【发布时间】:2013-06-15 02:30:34
【问题描述】:

(问题是并行的尴尬)

考虑一个包含 12 个单元的数组:

|__|__|__|__|__|__|__|__|__|__|__|__|

和四 (4) 个 CPU。

天真地,我会运行 4 个并行作业并为每个 CPU 提供 3 个单元。

|__|__|__|__|__|__|__|__|__|__|__|__|
=========|========|========|========|
   1 CPU    2 CPU    3 CPU    4 CPU

但是,看来,每个细胞都有不同的评估时间,有些细胞评估很快,有些则不然。

因此,我认为与其浪费“松弛的 CPU”,不如及时将每个单元提供给每个 CPU,并继续直到整个工作完成。

即:

开头:

|____|____|____|____|____|____|____|____|____|____|____|____|
 1cpu 2cpu 3cpu 4cpu

如果,2cpu 在单元格“2”完成了他的工作,它可以跳转到第一个空单元格“5”并继续工作:

|____|done|____|____|____|____|____|____|____|____|____|____|
 1cpu      3cpu 4cpu 2cpu
       |-------------->

如果1cpu完成,可以占用第六个单元:

|done|done|____|____|____|____|____|____|____|____|____|____|
           3cpu 4cpu 2cpu 1cpu 
  |------------------------>

以此类推,直到完成整个数组。

问题:

我不知道 先验 哪个单元“快”,哪个单元“慢”,所以我无法根据负载分配 cpu(cpu 越多越慢,越少越快)。 如何使用 MPI 实现这样的动态评估算法?

谢谢!!!!!!

更新

我用了一个很简单的方法,如何把整个job分成块,用IO-MPI:

给定:array[NNN] 和 nprocs - 可用工作单元的数量:

for (int i=0;i<NNN/nprocs;++i)
{
  do_what_I_need(start+i);
}
MPI_File_write(...);

其中“开始”对应于特定的排名编号。简而言之,我根据可用 CPU 的数量将整个 NNN 数组划分为固定大小的块,每个 CPU 执行其块,将结果写入(公共)输出并放松。

是否有可能以这样的方式更改代码(不完全重写主/从范式),使得每个 CPU 将只获得一次迭代(而不是 NNN/nprocs)并且在它完成它之后作业并将其部分写入文件,将继续下一个单元格而不是放松。

谢谢!

【问题讨论】:

  • 在 Windows API 中,有一个函数 TryEnterCriticalSection() 可用于创建您描述的行为。我没有使用 MPI 的经验,但它可能有类似的功能。
  • @quinxorin,我使用 GNU 并在 linux HPC 集群上工作,所以我无法使用它。不过谢谢你的建议!

标签: c++ dynamic mpi


【解决方案1】:

有一种众所周知的并行编程模式,有很多名称,其中一些是:任务包master / workertask farm、工作池等。这个想法是有一个单一的主进程,它将单元分配给其他进程(工人)。每个worker运行一个无限循环,在这个循环中它等待来自master的消息,计算一些东西然后返回结果。通过让主设备发送带有特殊标签的消息来终止循环。 worker可以使用通配符标签值MPI_ANY_TAG来接收不同标签的消息。

master 比较复杂。它还运行一个循环,但直到所有单元格都已处理完毕。最初它向每个工作人员发送一个单元格,然后开始一个循环。在这个循环中,它使用通配符源值MPI_ANY_SOURCE 接收来自任何工作人员的消息,如果有更多单元格要处理,则将其中一个发送给已返回结果的同一工作人员。否则,它会发送一条带有标签的消息,该标签设置为终止值。

在 Internet 上有很多很多现成的该模型的实现,甚至在 Stack Overflow 上也有一些实现(例如 this one)。请注意,此方案需要一个额外的 MPI 过程,而该过程通常做的工作很少。如果这是不可接受的,可以在单独的线程中运行工作循环。

【讨论】:

  • 谢谢!是的,我正在寻找一种“工人池”解决方案,因此我想知道是否有很好的 MPI 实现。我理解一个逻辑,它应该如何工作并且有大量可用资源(1024 cpu 的集群),所以一个额外的 MPI 进程是可以的。
  • 请查看主题更新和我的问题。
【解决方案2】:

您希望实现一种客户端-服务器架构,其中您有 workers 在他们下班时向 server 请求工作。

根据块的大小以及工作人员和服务器之间的通信速度,您可能需要调整发送给工作人员的块的大小。

【讨论】:

  • 确实,但我不知道先验,哪个块是耗时的。
  • 这就是为什么每个工人只分配了一小部分问题,例如你的问题中的一个单元格。我对块大小的评论的意思是,如果你的单元太小,以至于将单元与工作人员通信的开销超过了单元上的实际工作,你应该一次发送多个单元。跨度>
  • 请参阅主题更新和我的新问题。谢谢!
  • 您需要某种方式将单元动态分配给进程,因为您事先不知道每个单元的工作量。据我所知,使用客户端-服务器模型是最简单的解决方案。
【解决方案3】:

回答您更新的问题:

在主/从(或工作池,如果您喜欢这样标记)模型下,您基本上需要一个任务调度程序。主人应该知道哪些工作已经完成,哪些还需要做。 master 会给每个进程一些工作要做,然后坐下来等待进程完成(使用非阻塞接收和 wait_all)。一旦进程完成,让它将数据发送给主服务器,然后等待主服务器响应更多工作。继续这个直到工作完成。

【讨论】:

  • 谢谢!我会努力实现的!
猜你喜欢
  • 2014-02-04
  • 2015-02-11
  • 2010-09-15
  • 2017-09-21
  • 2022-01-10
  • 1970-01-01
  • 2013-04-18
  • 2012-09-13
  • 1970-01-01
相关资源
最近更新 更多