使用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是否已经这样做了。)
编辑:为清楚起见,我在问是否有一个自动启动所有根节点的功能。显然,我可以手动进行-上面的示例就是这样!
答案 0 :(得分:0)
这可能是对flow::graph
本身的误解。您必须通过在节点之间添加弧线以编程方式指定依赖项。您try_put
到图的第一个节点以启动它。这是创建图形的唯一方法。
如果您有想要触发图形运行的外部事件,则必须为该事件创建一个try_puts
侦听器,以启动图形。
您可以创建一个永不返回的multifunction_node
,您可以在其中查找事件并发送消息,但这是TBB的不良设计。您将把TBB任务永久锁定到该multifunction_node,这是不行的。而且您仍然必须try_put
multifunction_node
进行一些操作才能启动它。