フローグラフの基本: single-push と broadcast-push

インテル® スレッディング・ビルディング・ブロック (インテル® TBB) のフローグラフのノードは、メッセージを push/pull することで通信します。ノードの種類に応じて、メッセージの push には 2 つのポリシーが使用されます。

次のコードは、2 つのポリシーの違いを示します。

using namespace tbb::flow;

tbb::atomic<size_t> g_cnt;

struct fn_body1 {
    tbb::atomic<size_t> &body_cnt;
    fn_body1(tbb::atomic<size_t> &b_cnt) : body_cnt(b_cnt) {}
    continue_msg operator()( continue_msg /*dont_care*/) {
        ++g_cnt;
        ++body_cnt;
        return continue_msg();
    }
};

void run_example1() {  // Flow_Graph_Single_Vs_Broadcast.xml 用のサンプル
    graph g;
    tbb::atomic<size_t> b1;  // 各 function_node ボディーの
    tbb::atomic<size_t> b2;  // ローカルカウント
    tbb::atomic<size_t> b3;  //
    function_node<continue_msg> f1(g,serial,fn_body1(b1));
    function_node<continue_msg> f2(g,serial,fn_body1(b2));
    function_node<continue_msg> f3(g,serial,fn_body1(b3));
    buffer_node<continue_msg> buf1(g);
    //
    // single-push ポリシー
    //
    g_cnt = b1 = b2 = b3 = 0;
    make_edge(buf1,f1);
    make_edge(buf1,f2);
    make_edge(buf1,f3);
    buf1.try_put(continue_msg());
    buf1.try_put(continue_msg());
    buf1.try_put(continue_msg());
    g.wait_for_all();
    printf( "after single-push test, g_cnt == %d, b1==%d, b2==%d, b3==%d\n", (int)g_cnt, (int)b1, (int)b2, (int)b3);
    remove_edge(buf1,f1);
    remove_edge(buf1,f2);
    remove_edge(buf1,f3);
    //
    // broadcast-push ポリシー
    //
    broadcast_node<continue_msg> bn(g);
    g_cnt = b1 = b2 = b3 = 0;
    make_edge(bn,f1);
    make_edge(bn,f2);
    make_edge(bn,f3);
    bn.try_put(continue_msg());
    bn.try_put(continue_msg());
    bn.try_put(continue_msg());
    g.wait_for_all();
    printf( "after broadcast-push test, g_cnt == %d, b1==%d, b2==%d, b3==%d\n", (int)g_cnt, (int)b1, (int)b2, (int)b3);
}

以下は、このサンプルコードの出力です。

after single-push test, g_cnt == 3, b1==3, b2==0, b3==0
after broadcast-push test, g_cnt == 9, b1==3, b2==3, b3==3

single-push テストは、"single-push" ポリシーに従ってメッセージを転送する buffer_node を使用します。buffer_node に 3 つのメッセージを送ると、3 つのメッセージが push されます。また、最初の function_node にのみ送られることが分かります。一般に、メッセージを受け付けることができるサクセサーが複数ある場合に特定のノードに push するポリシーはありません。

broadcast-push テストは、受け取ったメッセージを受け付けることができるすべてのサクセサーに push する broadcast_node を使用します。broadcast_node に 3 つのメッセージを送ると、function_nodes に合計 9 つのメッセージが push されます。

バッファーをサポートする (メッセージを保持し転送する) ノードのみ "single-push" ポリシーにできます。それ以外のノードはすべて "broadcast-push" になります。詳細は、「フローグラフのヒントとコツ」セクションの「1 つまたは複数のサクセサーへの送信」と「インテル® TBB リファレンス・マニュアル」の「フローグラフ」セクションにある「転送、バッファー、受信ポリシー」を参照してください。

関連情報