是否可以动态控制 TBB Flow Graph 中的执行路径,使用节点的输出作为条件变量来确定是否应该启动另一个节点?
问问题
1461 次
1 回答
5
有几种方法可以动态控制消息在 flow::graph 中的位置:
您可以将消息显式放置到节点主体中的其他节点。请注意,func_body
将消息放入f1
or f2
,具体取决于其输入的值。节点没有被 附加make_edge()
,因为消息流不受图的拓扑控制:
template<typename T>
struct func_body {
typedef tbb::flow::function_node<T,T> target_node_type;
target_node_type &my_n1;
target_node_type &my_n2;
func_body(target_node_type &node1, target_node_type &node2) : my_n1(node1), my_n2(node2) {}
tbb::flow::continue_msg operator()(const T& in) {
// do some computation
bool send_to_one = in > 0;
if(send_to_one) my_n1.try_put(in);
else my_n2.try_put(in);
return tbb::flow::continue_msg(); // message is discarded if no successor exists
}
};
struct otherbody {
int operator()(const int& in) {
return in;
}
};
int
main() {
tbb::flow::graph g;
tbb::flow::function_node<int,int> f1(g, tbb::flow::unlimited, otherbody());
tbb::flow::function_node<int,int> f2(g, tbb::flow::unlimited, otherbody());
tbb::flow::function_node<int> cn(g, tbb::flow::unlimited, func_body<int>(f1,f2));
}
或者您可以使用 a multifunction_node
(注意tuple
和get
模板的类型在tbb::flow
命名空间中,而不是std::
像旧文档中那样。)注意在这种情况下,我们将f1
和附加f2
到multifunction_node
.
typedef tbb::flow::multifunction_node<int,tbb::flow::tuple<int,int> > mfnode;
struct mfunc_body {
void operator()(const int& in, mfnode::output_ports_type &op) {
// do some computation
bool send_to_one = in > 0;
if(send_to_one) tbb::flow::get<0>(op).try_put(in);
else tbb::flow::get<1>(op).try_put(in);
}
};
struct otherbody {
int operator()(const int& in) {
return in;
}
};
int
main() {
tbb::flow::graph g;
tbb::flow::function_node<int,int> f1(g, tbb::flow::unlimited, otherbody());
tbb::flow::function_node<int,int> f2(g, tbb::flow::unlimited, otherbody());
mfnode cn(g, tbb::flow::unlimited, mfunc_body());
tbb::flow::make_edge(tbb::flow::output_port<0>(cn), f1);
tbb::flow::make_edge(tbb::flow::output_port<1>(cn), f2);
// ...
}
目前这两种方法在功能上是相同的;每个都会产生一个任务来执行function_nodes
. 将来,multifunction_node
如果只有一个输出端口,情况可能会优化为不生成try_put()
。
于 2013-07-29T19:42:00.350 回答