Lightweight policy

Summary

Policy for functional nodes that helps to reduce the overhead associated with the execution scheduling of the node. This policy should only be applied on a per-node basis after careful evaluation.

Description

The lightweight policy indicates that the body of the node contains a small amount of work and should, if possible, be executed without the overhead of scheduling a task. All Flow Graph functional nodes, except for source_node, support the lightweight policy as a possible value of the Policy template parameter. To use the lightweight policy, specify the Policy template parameter of the node to queueing_lightweight, rejecting_lightweight, or lightweight. For functional nodes that have a default value for the Policy template parameter, specifying the lightweight policy results in extending the behavior of the default value of Policy with the behavior defined by the lightweight policy. For example, if the default value of Policy is queueing, specifying lightweight as the Policy value is equivalent to specifying queueing_lightweight.

Caution

Having multiple successors with lightweight policy for a particular node can significantly reduce the parallelism available in the graph.

Caution

Cycles in a flow graph consisting only of nodes with lightweight policies might lead to deadlock.

Example

The example below shows the application of the lightweight policy to a graph with a pipeline topology. It is reasonable to apply the lightweight policy to the second and third nodes because the bodies of these nodes are small. This allows the second and third nodes to execute without task scheduling overhead. The lightweight policy is not specified for the first node in order to permit concurrent invocations of the graph.

#include "tbb/flow_graph.h"

int main() {
    using namespace tbb::flow;

    graph g;

    function_node< int, int > add( g, unlimited, [](const int &v) {
        return v+1;
    } );
    function_node< int, int, lightweight > multiply( g, unlimited, [](const int &v) {
        return v*2;
    } );
    function_node< int, int, lightweight > cube( g, unlimited, [](const int &v) {
        return v*v*v;
    } );

    make_edge(add, multiply);
    make_edge(multiply, cube);

    for(int i = 1; i <= 10; ++i)
        add.try_put(i);
    g.wait_for_all();

    return 0;
}

See also: