Оптимально проходить DAG с взвешенными вершинами параллельно - PullRequest
1 голос
/ 14 июня 2019

Существует график, на котором вершины представляют фрагменты кода, а ребра - зависимости между ними.Кроме того, каждая вершина имеет два числа: сколько потоков может использовать соответствующий фрагмент кода (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-зависимостей мы имеем FG и AH.Для E, AC и ABD.Чтобы добраться до J, нам нужно 0.3x для AH и 0.4x для FG, но для этого нужно много потоков.Мы могли бы сначала запустить A и F параллельно (каждый с одним потоком).Тогда мы будем запускать G с 7 потоками и, когда A заканчивает, H с 1 потоком.Однако есть также ветвь E.В идеале, мы хотели бы, чтобы он был готов на 0,5 позже, чем J. В этом случае это довольно просто, потому что самый длинный путь к E, когда мы уже обработали A, занимает 0,4 с использованием одного потока, а другой путь занимает меньше, чем это и использует только2 потока - так что мы можем выполнить эти вычисления, когда J работает.Но если, скажем, для D потребовалось 0,6x, нам, вероятно, нужно было бы запустить его параллельно с G.

Так что я думаю, что я мог бы начать с вершины стока и сбалансировать веса подграфов, от которых это зависит,Но, учитывая эти «н-нить» задачи, не совсем понятно как.И, учитывая, что x-числа являются лишь оценками, было бы хорошо, если бы он мог внести коррективы, если бы конкретные задачи заняли больше или меньше времени, чем предполагалось.

1 Ответ

2 голосов
/ 14 июня 2019

Вы можете смоделировать эту проблему как задачу планирования работы магазина (в частности, проблема гибкой работы магазина, когда машины - это процессоры, а задания - это кусочки программ, которые нужно запустить).
Первыйвам нужно немного изменить свой DAG, чтобы преобразовать его в другой DAG, представляющий собой дизъюнктивный граф , представляющий вашу проблему.
Это преобразование очень простое.Для любого узла i, t, nb_t, представляющего задание i, для которого необходимо выполнить t секунд с 1 потоком и который можно распараллелить на потоки nb_t, выполните следующие действия:
Замените i, t, nb_t на nb_t вершин i_1, t/nb_t, ..., i_(nb_t), t/nb_t.Для каждого входящего / исходящего фронта узла i создайте входящий / исходящий фронт от / до всех вновь создаваемых узлов.По сути, мы просто разделяем каждое задание, которое может быть распараллелено, на более мелкие задания, которые могут обрабатываться несколькими процессорами (машинами) одновременно.
Затем у вас есть дизъюнктивный граф, который является входом для задачи магазина заданий.

Тогда все, что вам нужно сделать, это решить эту хорошо известную проблему, доступны различные варианты ....
Я бы посоветовал использовать решатель MILP, но из небольшого поиска я только что сделалкажется, что многие метаэвристики могут решить эту проблему (имитация отжига, генетическое программирование, ...).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...