フローグラフの基本: 単一プッシュとブロードキャスト・プッシュ

フローグラフの基本: 単一プッシュとブロードキャスト・プッシュ#

oneAPI スレッディング・ビルディング・ブロック (oneTBB) フローグラフ内のノードは、メッセージをプッシュおよびプルすることで通信します。ノードのタイプに応じて、メッセージのプッシュには 2 つのポリシーが使用されます。

  • 単一プッシュ: ノードに後継ノードがいくつ存在し、メッセージを受け入れることができるかに関係なく、各メッセージは 1 つの後継ノードにのみ送信されます。

  • ブロードキャスト・プッシュ: メッセージは、プッシュモードでエッジによってノードに接続され、メッセージを受け入れるすべての後続ノードにプッシュされます。

次のコードはこの差異を示します。

using namespace oneapi::tbb::flow; 

std::atomic<size_t> g_cnt; 

struct fn_body1 { 
    std::atomic<size_t> &body_cnt; 
    fn_body1(std::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; 
    std::atomic<size_t> b1; // local counts 
    std::atomic<size_t> b2; // for each function _node body 
    std::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); 
    // 
    // 単一プッシュポリシー 
    //
     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_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

単一プッシュのテストでは、メッセージを転送する「単一プッシュ」ポリシーを持つ buffer_node を使用します。3 つのメッセージを buffer_node に配置すると、3 つのメッセージがプッシュされます。また、最初の function_node のみが送信されることにも注意してください。一般に、複数の後続ノードが受け入れ可能な場合、どのノードにプッシュされるか決定するポリシーはありません。

ブロードキャスト・プッシュのテストでは、受信したメッセージをすべての受け入れて、後続ノードにプッシュする broadcast_node を使用します。3 つのメッセージを broadcast_node に送信すると、合計 9 つのメッセージが function_nodes にプッシュされます。

バッファリング (受信したメッセージを保持して転送) するように設計されたノードのみが「単一プッシュ」ポリシーを持ち、その他のすべてのノードは「ブロードキャスト・プッシュ」ポリシーを持ちます。

フローグラフのヒントとコツ1 つまたは複数の後続ノードに送信するフローグラフの基本: バッファリングと転送を参照してください。