フローグラフの基本: 単一プッシュとブロードキャスト・プッシュ#
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 つまたは複数の後続ノードに送信するとフローグラフの基本: バッファリングと転送を参照してください。