如何启动所有没有依赖关系的TBB continue_nodes

时间:2018-12-14 15:53:24

标签: c++ tbb

使用TBB,您可以使任务很好地进行DAG,并且可以自动并行运行它们。 Example from the documentation

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 :(得分:0)

这可能是对flow::graph本身的误解。您必须通过在节点之间添加弧线以编程方式指定依赖项。您try_put到图的第一个节点以启动它。这是创建图形的唯一方法。

如果您有想要触发图形运行的外部事件,则必须为该事件创建一个try_puts侦听器,以启动图形。

您可以创建一个永不返回的multifunction_node,您可以在其中查找事件并发送消息,但这是TBB的不良设计。您将把TBB任务永久锁定到该multifunction_node,这是不行的。而且您仍然必须try_put multifunction_node进行一些操作才能启动它。