1

使用 TBB,您可以创建一个不错的 DAG 任务,并且它可以自动并行运行它们。文档中的示例

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 是否已经这样做了。)

编辑:要清楚,我问是否有自动启动所有根节点的功能。显然我可以手动完成 - 这就是上面的例子!

4

1 回答 1

0

这大概是对flow::graph自己的误解。您必须通过在节点之间添加弧以编程方式指定依赖关系。你try_put到图的第一个节点来启动它。这是开始图表的唯一方法。

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

您可以创建一个multifunction_node永不返回的,您可以使用它来查找事件和发送消息,但这是糟糕的 TBB 设计。您会将 TBB 任务永久锁定到该多功能节点,这是不行的。你仍然需要try_put一些东西multifunction_node来启动它。

于 2018-12-14T21:44:16.420 回答