如何:TBB节点具有多个异步输入和多个输出

时间:2013-11-16 01:39:58

标签: c++ tbb

我是线程构建模块(TBB)的新手;我需要用TBB节点实现以下逻辑:

N型节点接收两个输入;例如: 1. std :: vector //数据 2. bool // flag

这些输入是异步的。

如果输入类型为1,则处理N类节点拥有的数据以生成两个输出,例如: 一个。的std ::矢量 湾INT

如果输入类型为2,则处理N类节点所拥有的数据以生成一个输出,例如std :: vector。

我一直在尝试使用tbb :: flow :: or_node来表达输入部分,使用tbb :: flow :: multifunction_node来输出部分。

如果只有一个输入和多个输出,这个逻辑可以用tbb :: flow :: multifunction_node编写(我测试过,它可以工作)。如果有一个输出和多个输入,我找到了说明解决方案的代码示例。但是,我不清楚如何使用TBB框架实现多个异步输入和多个输出的情况。建议欢迎。

1 个答案:

答案 0 :(得分:3)

您应该能够使用当前的or_node实现执行您想要的操作。 (我们正在重新设计or_node的输出以使其更友好,但我们需要像你这样的用户输入有关or_node社区预览功能的问题。)

要记住的一件事是在使用or_node编译代码时打开CPF。开关是-DTBB_PREVIEW_GRAPH_NODES = 1。

# define TBB_PREVIEW_GRAPH_NODES 1  // necessary to turn on the or_node community Preview Feature.
#include "tbb/flow_graph.h"
#include <vector>

using namespace tbb::flow;

// The output format of the or_node is a struct that contains
//   1. the index of the input that the message appeared on, and
//   2. a tuple, the (i-1)th element of which is the message received

typedef or_node<tuple<std::vector<double>, bool> > my_or_node_type;

// it wasn't clear from the description if you wanted to differentiate between the vectors output with
// an input of type 1. or type 2.  If you need to do that you can add an extra output port to the multifunction_node.
typedef multifunction_node<my_or_node_type::output_type, tuple<std::vector<double>, int> > my_mf_node_type;

struct mf_node_body {
    void operator()(const my_or_node_type::output_type &in, my_mf_node_type::output_ports_type &op) {
        switch(in.indx) {
        case 0: {
                // do the operation for the first input (the std::vector) The vector will be in
                // get<0>(in.result).  Remember you are copying vectors here, so if you have big
                // vectors you will probably want to do some buffer management on your own and
                // pass refs to the vector instead.
            }
            break;
        case 1: {
                // do the operation signaled by the second input (the bool.)  The value of the
                // input is in get<1>(in.result).
            }
            break;
        }
    }
};


main() {
    graph g;
    my_or_node_type multi_in(g);
    my_mf_node_type multi_out(g, unlimited, mf_node_body());

    // if the vector-producing node is called vpn, you attach it to the 0-th input of the or_node with
    //     make_edge(vpn, input_port<0>(multi_in));
    //
    // the bool-producing node bn can be attached similarly:
    //     make_edge(bn, input_port<1>(multi_in);
    //
    // attach the multi-in to the multi-out:
    //     make_edge(multi_in, multi_out);
    //
    // attach the vector consumer node vcn
    //     make_edge(output_port<0>(multi_out), vcn);
    //
    // attach the integer output to the int consuming node icn
    //     make_edge(output_port<1>(multi_out), icn);
    // 
    // start up the graph and make sure to do a wait_for_all() at the end.
}

请记住,multifunction_node主体是并行调用的,所以它所做的工作不应该有竞争条件(除非你出于某种原因想要竞争条件。)你可以使节点主体按顺序执行使用serial而不是unlimited构建它。确保您可以安全地销毁图形的唯一方法是确保没有任务正在执行任何节点。执行此操作的最佳方法是执行g.wait_for_all()

此致 克里斯

P.S。 - 一个附录。如果multifunction_node被定义为serial,它将具有输入缓冲区,除非您明确地将其排除。如果您不希望缓冲区存在,这可能会改变图形的行为。