(问题是令人尴尬的并行)
考虑由12个单元组成的数组:
|__|__|__|__|__|__|__|__|__|__|__|__|
和四(4)个CPU。
天真的,我要运行4个并行作业,并向每个CPU馈送3个单元。
|__|__|__|__|__|__|__|__|__|__|__|__|
=========|========|========|========|
1 CPU 2 CPU 3 CPU 4 CPU
但是似乎每个单元都有不同的评估时间,一些单元的评估非常快,而有些则没有。
因此,我认为不要浪费“松弛的CPU”,而是将EACH单元及时送入每个CPU,并继续进行直到完成整个工作为止。
即:
开始时:
|____|____|____|____|____|____|____|____|____|____|____|____|
1cpu 2cpu 3cpu 4cpu
如果2cpu在单元“2”处完成了工作,则它可以跳到第一个空单元“5”并继续工作:
|____|done|____|____|____|____|____|____|____|____|____|____|
1cpu 3cpu 4cpu 2cpu
|-------------->
如果1cpu完成,则可以占用第六个单元格:
|done|done|____|____|____|____|____|____|____|____|____|____|
3cpu 4cpu 2cpu 1cpu
|------------------------>
依此类推,直到完成整个阵列。
问题:
我不知道哪个单元格是“快速”而哪个单元格是“慢”的先验知识,因此我无法根据负载来分配cpus(越多的cpus越慢,少的就越快)。
如何使用MPI实现这种用于动态评估的算法?
谢谢!!!!!
更新
我使用一种非常简单的方法,如何使用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),并且在完成工作并写入之后将其部分保留到文件中,将继续到下一个单元格并且不要放松。
谢谢!
最佳答案
有一个众所周知的并行编程模式,有很多名称,其中有一些:任务包,主/工作器,任务场,工作池等。其思想是拥有一个主进程,该主进程将单元分发到其他过程( worker )。每个工作程序都会运行一个无限循环,在该循环中,它等待主服务器发出的消息,进行计算,然后返回结果。通过让主机发送带有特殊标签的消息来终止循环。 worker 可以使用通配符标签值MPI_ANY_TAG
接收带有不同标签的消息。
主人更复杂。它还运行一个循环,但是直到所有单元都已处理完毕。最初,它向每个工作人员发送一个单元,然后开始循环。在此循环中,它使用MPI_ANY_SOURCE
的通配符源值从任何工作程序接收一条消息,如果还有更多要处理的单元格,则将其中一个发送给返回结果的同一工作程序。否则,它将发送带有设置为终止值的标签的消息。
Internet上有很多这种模型的现成实现,甚至有一些Stack Overflow(例如this one)。请注意,此方案需要一个额外的MPI流程,而该流程通常做的很少。如果不能接受,则可以在单独的线程中运行工作程序循环。
关于c++ - 使用MPI的不平衡负载(v2.0),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17071069/