limiter_node の使用

limiter_node の使用#

リソースの消費を制限する 1 つの方法は、limiter_node を使用して、グラフ内の特定のポイントを通過するメッセージ数を制限することです。Limiter_node のコンストラクターは 2 つの引数を受け取ります。

limiter_node( graph &g, size_t threshold )

最初の引数は、それが属するグラフへの参照です。2 番目の引数は、ノードが受信メッセージを拒否する前に通過が許可される項目の最大数を設定します。

limiter_node は、通過を許可したメッセージの内部カウントを維持します。メッセージがグラフの制御を離れると、limiter_node のデクリメント・ポートにメッセージを送信してカウントを減らし、追加のメッセージを通過させることができます。以下の例では、input_nodeM 個の大きなオブジェクトを生成します。しかし、ユーザーは、一度に最大 3 つの大きなオブジェクトが function_node に到達できるようにし、input_node が一度に M 個の大きなオブジェクトのすべてを生成しないようにしたいと考えています。

graph g; 

int src_count = 0; 
int number_of_objects = 0; 
int max_objects = 3; 

input_node< big_object * > s( g, [&]( oneapi::tbb::flow_control& fc ) -> big_object* { 
    if ( src_count < M ) { 
        big_object* v = new big_object(); 
        ++src_count; 
        return v; 
    } else { 
        fc.stop(); 
        return nullptr; 
    } 
} ); 
s.activate(); 

limiter_node< big_object * > l( g, max_objects ); 

function_node< big_object *, continue_msg > f( g, unlimited, 
    []( big_object *v ) -> continue_msg { 
        spin_for(1); 
        delete v; 
        return continue_msg(); 
} ); 

make_edge( l, f ); 
make_edge( f, l.decrement ); 
make_edge( s, l ); 
g.wait_for_all();

上記の例では、input_nodeM 個の大きなオブジェクトが一度にすべてを生成するのを防ぎます。limiter_node のしきい値は 3 であるため、内部カウントが 3 に達すると、受信メッセージを拒否します。input_node はメッセージが拒否されたことを認識すると、ボディー・オブジェクトの呼び出しを停止し、最後に生成された値を一時的にバッファリングします。function_node の出力である continue_msg は、limiter_node のデクリメント・ポートに送信されます。そして、実行が完了すると、limiter_node の内部カウントがデクリメントされます。内部カウントがしきい値を下回ると、input_node からメッセージが再び流れ始めます。この例では、一度に最大 4 つの大きなオブジェクトが存在しまが、そのうち 3 つは limiter_node を通過し、1 つは input_node にバッファリングされます。