并行编程实战——TBB节点类型

235 篇文章 94 订阅

一、TBB中的节点

在TBB框架的应用中,是离不开节点这个概念的。大家可以把数据的处理、计算、中转、保存以及调度方式等理解成一个节点的抽象化。可以这样理解,TBB的运行基本是以节点为基础的。从后期的开发也可以看出,整个TBB其实是一个图(Graph)为运行框架,而节点就是图中的必须。
在稍微复杂一些算法结构中,都可以或多或少的看到图的身影,TBB中的图和离散数学或者算法中的图基本类似。所以有过这些基础的开发者应该很容易明白这个概念,同样也就很容易明白节点的概念。

二、节点类型

正因为TBB的图结构,所以其节点承担起主要的功能任务。而根据具体的功能需求不同,可以划分出不同的类型节点。下面就这些预定义节点进行一下分析说明:
1、input_node
输入节点,很容易理解,数据的输入或者起始的驱动节点。当它变成活动节点后,会产生输出动作(当然可以在输出前完成一系列的自定义动作)。它的输出方向由节点的连接控制(可以理解成图的流向)。在连接成功的前提下,输入节点和其连接节点会进行数据的交互。需要注意的是,无论是输入还是连接的节点都可以进行缓冲队列的设置,来处理节点间数据处理速度的简单不匹配。
它是一个通用的输入输出类型节点,单输出的,可以对所有的后续连接节点进行广播数据。
2、function_node
功能节点,一个单输入单输出的节点,它同样对数据进行广播转发。也可以对节点的并发和缓冲进行设置。对于每个输入只返回一个输出。

3、continue_node
它是一个单输入、单输出节点,数据进行广播发送。它的输入需要大于等于1个continue_msg类型的输入且具有通用输出类型。当接收的消息大于1时,此节点会根据输入偏移利用前置器进行continue_msg消息的处理。

4、multifunction_node
功能与function_node类似,它也有一个输入,区别在于,它有多个输出的节点。

5、broadcast_node
广播节点,单输入输出节点,如字面意义一样,把得到的数据广播给所有的连接节点,注意,它不对数据进行缓冲。

6、buffer_node, queue_node, priority_queue_node, and sequencer_node.
缓冲节点,这些类型节点都是缓冲节点。它们是单输入单输出的节点,更为需要说明的是它还是一个单播节点,即它只能发送给一个后续节点。而不是前面的广播给所有的后续连接节点。

7、join_node
组合节点,从名字就可以理解它是一个多输入单输出节点。它从多个输入节点中创建一个元组(Tuple)来处理所有的输入消息并将其广播给后续的连接节点。组合的策略可以进行设置,包括队列、持有或标签匹配等 。

8、split_node
这个和上面的正好相反,它是一个单输入多输出的节点,可以理解为对输入节点的消息进行了分裂操作。为了能够分离或者说分裂输入消息,接收的是一个元组类型,然后在不同的输出端口上输出元组的相应的元素类型消息。
9、write_once_node, overwrite_node
单输入单输出节点,缓冲并广播给后续节点。广播后,节点保留最后收到的消息,所以后续节点仍然可以继续应用它。write_once_node只接收收到的第一条消息,而后者则可以接收所有消息,将它们广播给连接的节点。同时,将保留的老数据更新为后续新数据。

10、limiter_node
限制节点,是一个多输入单输出的节点,不缓存消息,对接收的消息数据进行广播转发。它通过内部的一个流量限制器对广播的消息进行限制控制,当消息广播的数量达到阀值后则停止广播消息。可以通过特殊的输入商品来调整这个流量限制器。它的主输入和输出具有相同的数据类型。

11、indexer_node
索引器节点,多输入、单输出节点,并对收到的消息进行广播转发。它的特点在于index,输入的数据中具有标签标识(index),即数据从哪个输入节点获取。其输入消息类型为泛型类型的列表,输出类型则为tagged_msg。
12、composite_node
聚合节点,可能有0~N个输入输出端口的节点。特点就在于composite,它可以对节点的数据打包并利用元组进行数据的处理。然后再形成新的图任务。简单的理解就是,将多个图中的子任务进行聚合,形成一个新的大任务,减少任务处理的数量,提高并行的效率。

13、async_node (preview feature)
一个预览的特征,异步节点。其实就是允许图与外界节点进行通信。

当然,这些预定义的类型节点,不可能满足所有的实际场景,这就需要继承TBB库的一些基类来自定义自己的节点类型。它们一般在头文件flow_graph.h中,主要包括graph_node、类sender和类receiver。下面看一下graph_node的定义:

//_flow_graph_impl.h
//! The base of all graph nodes.
class graph_node : tbb::internal::no_copy {
    friend class graph;
    template<typename C, typename N>
    friend class graph_iterator;

#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
    friend class internal::get_graph_helper;
#endif

protected:
    graph& my_graph;
    graph_node *next, *prev;
public:
    explicit graph_node(graph& g);

    virtual ~graph_node();

#if TBB_PREVIEW_FLOW_GRAPH_TRACE
    virtual void set_name(const char *name) = 0;
#endif

#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
    virtual void extract() = 0;
#endif

protected:
    // performs the reset on an individual node.
    virtual void reset_node(reset_flags f = rf_reset_protocol) = 0;
}; 

有过TBB节点开发经验的就会看出其基本的图节点的内容。

三、总结

在节点的应用中,要注意区分单输入(输出)、多输入(输出)与广播、单播的不同。前者指只有一个输入输出的节点,后者指的是数据转发的方式。一般来说,前者控制的是节点中控制数据流的点的数量,后者指的是连接发送的策略。
TBB的应用还是有很多细节可挖的,可惜一般的地方用不到这个框架。有兴趣的可以一起学习分析。

  • 9
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值