Как запустить все TBB continue_nodes, которые не имеют зависимостей - PullRequest
0 голосов
/ 14 декабря 2018

С помощью TBB вы можете создавать отличные группы задач и автоматически запускать их параллельно. Пример из документации :

typedef continue_node< continue_msg > node_t;
typedef const continue_msg & msg_t;

int main() {
  tbb::flow::graph g;
  node_t A(g, [](msg_t){ a(); } );
  node_t B(g, [](msg_t){ b(); } );
  node_t C(g, [](msg_t){ c(); } );
  node_t D(g, [](msg_t){ d(); } );
  node_t E(g, [](msg_t){ e(); } );
  node_t F(g, [](msg_t){ f(); } );
  make_edge(A, B);
  make_edge(B, C);
  make_edge(B, D);
  make_edge(A, E);
  make_edge(E, D);
  make_edge(E, F);
  A.try_put( continue_msg() );
  g.wait_for_all();
  return 0;
}

Это прекрасно работает, однако предполагает, что у меня есть какой-то известный корневой узел, и все узлы являются зависимыми от этого узла.Что если у меня есть более общая сеть, в которой может быть несколько корневых узлов?

int main() {
  tbb::flow::graph g;

  // Imagine a function did this but in a generic way:      
  node_t A(g, [](msg_t){ a(); } );
  node_t B(g, [](msg_t){ b(); } );
  node_t C(g, [](msg_t){ c(); } );
  node_t D(g, [](msg_t){ d(); } );
  node_t E(g, [](msg_t){ e(); } );
  node_t F(g, [](msg_t){ f(); } );
  make_edge(A, B);
  make_edge(B, C);
  make_edge(D, E);

  // Now how do I now do this?
  A.try_put( continue_msg() );
  D.try_put( continue_msg() );
  F.try_put( continue_msg() );

  g.wait_for_all();
  return 0;
}

Надеюсь, этот пример понятен - в основном у меня есть множество задач, но зависимости между ними являются динамическими, поэтому они могут закончитьсяне зависит друг от друга вообще.Как мне сказать TBB: «Хорошо, я хочу, чтобы все эти задачи выполнялись».

(Очевидно, я могу вручную подсчитать количество зависимостей для каждой задачи, но я спрашиваю, делает ли TBB это уже.)

Редактировать: Для ясности, я спрашиваю, есть ли функция, которая автоматически запускает все корневые узлы.Очевидно, я могу сделать это вручную - это то, что делает пример выше!

1 Ответ

0 голосов
/ 15 декабря 2018

Вероятно, это неправильное понимание самой flow::graph.Вы должны указать зависимости программно, добавив дуги между узлами.Вы try_put к первому узлу графика, чтобы запустить его.Это единственный способ запустить график.

Если у вас есть внешние события, которые вы хотите запустить график, вы должны создать прослушиватель этого события, который try_puts, чтобы запустить график.

Вы можете создать multifunction_node, который никогда не возвращается, который вы можете искать события и отправлять сообщения, но это плохой дизайн TBB.Вы бы навсегда заблокировали задачу TBB для этого многофункционального узла, нет-нет.И вам все еще нужно try_put что-то, чтобы multifunction_node запустить его.

...