最佳地并行遍历带有加权顶点的DAG

时间:2019-06-13 21:47:52

标签: multithreading algorithm graph-theory directed-acyclic-graphs

有一个图,其中顶点表示代码段,边表示它们之间的依赖关系。此外,每个顶点都有两个数字:相应的代码段可以使用多少个线程(1、2,...或“与内核一样多”),以及估计获得多少时间。那么多线程(与其他线程相比,例如1、0.1或10)。想法是并行运行代码片段,以考虑其依赖性,从而为它们提供这样的线程数,以使总执行时间最小。

是否有一些现有的算法可以做到这一点或可以用作基础?

到目前为止,我的想法如下。例如,我们共有8个线程(因此NT = 8T)和下图。

  +----------------+         +----------------+
+-+ A: 0.2x, 1T    +----+    | F: 0.1x, 1T    |
| +---+------------+    |    +---+------------+
|     |                 |        |
| +---v------------+    |    +---v------------+
| | B: 0.1x, 2T    +-+  |    | G: 0.3x, NT    +-+
| +----------------+ |  |    +----------------+ |
|                    |  |                       |
| +----------------+ |  |    +----------------+ |
+-> C: 0.4x, 1T    | |  +----> H: 0.1x, 1T    | |
  +--+-------------+ |       +--+-------------+ |
+----+               |          |               |
| +----------------+ |       +--v-------------+ |
| | D: 0.1x, 1T    <-+       | J: 1.5x, 4T    <-+
| +--+-------------+         +-------+--------+
|    |                               |
| +--v-------------+                 |
+-> E: 1.0x, 4T    +------------+    |
  +----------------+            |    |
                             +--v----v--------+
                             + I: 0.01x, 1T   |
                             +----------------+

在任务I中,我们有2个依赖项,E和J。作为J依赖项,我们有F-G和A-H。对于E,A-C和A-B-D。要达到J,我们在A-H上需要0.3倍,在F-G上需要0.4倍,但是G需要很多线程。我们可以首先并行运行A和F(每个都有一个线程)。然后,我们将使用7个线程运行G,而当A完成时,将使用1个线程运行H。但是,还有E分支。理想情况下,我们希望它比J早0.5就绪。在这种情况下,这很容易,因为已经使用一个线程处理了A时,到E的最长路径使用一个线程占用0.4,而另一个路径占用的路径少于这个并且仅使用2个线程-因此我们可以在J运行时运行这些计算。但是,如果说D花费了0.6倍,我们可能还需要与G并行运行。

所以我想我可以从水槽顶点开始,平衡它所依赖的子图的权重。但是,鉴于这些“ N线程”任务,如何执行尚不十分清楚。考虑到x数只是估计值,如果特定任务花费的时间比预期的长或短,则可以进行调整将是很好的。

1 个答案:

答案 0 :(得分:2)

您可以将此问题建模为job shop scheduling problem(特别是灵活的作业车间问题,其中机器是处理器,而作业是要运行的程序的一部分)。
首先,您必须稍微修改一下DAG,才能将其转换为另一个代表问题的disjunctive graph DAG。
这种转换非常简单。对于表示作业i, t, nb_t的任何节点i,需要1个线程执行t秒,并且可以并行化为nb_t个线程,请执行以下操作: br /> 将i, t, nb_t替换为nb_t顶点i_1, t/nb_t,...,i_(nb_t), t/nb_t。对于节点i的每个传入/传出边缘,从/到所有新创建的节点创建传入/传出边缘。基本上,我们只是将每个可以并行化的作业拆分为可以同时由多个处理器(机器)处理的较小作业。
然后,您将获得析取图,这是车间问题的输入。

然后,您需要做的就是解决这个众所周知的问题,有不同的选择....
我会建议使用MILP求解器,但是从我刚才做的小搜索看来,似乎许多元启发式算法都可以解决该问题(模拟退火,遗传编程等)。