c++ - TBB flow graph conditional execution -
it possible control execution path in tbb flow graph dynamically, using output of node condition variable determine whether node should launched?
there couple ways dynamically control messages go in flow::graph:
you can explicitly put messages other nodes in body of node. notice func_body
puts message f1
or f2
, depending on value of input. nodes not attached make_edge()
, because flow of messages not controlled topology of graph:
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) { // 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 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)); }
or can use multifunction_node
(note types of tuple
, get
templates in tbb::flow
namespace, not std::
in old documentation.) notice in case attach f1
, f2
output ports of 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) { // 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); // ... }
currently these 2 methods functionally-identical; each spawn task execute body of function_nodes
. in future multifunction_node
case may optimized not spawn if 1 output port try_put()
to.
Comments
Post a Comment