使用代码解决上面的问题
一、实例所使用的链接
1.Message Flow Graph Example
https://spec.oneapi.io/versions/1.1-rev-1/elements/oneTBB/source/flow_graph/message_flow_graph_example.html
2.concurrent_map
https://spec.oneapi.io/versions/1.1-rev-1/elements/oneTBB/source/containers/concurrent_map_cls.html
二、实例
#include <tpf_output.hpp>
#include <tbb/tbb.h>
/*
编译指令
g++ -std=c++20 flow.cpp -ltbb12 -o g.exe
clang -std=c++20 flow.cpp -ltbb12 -o c.exe
cl /EHsc /std:c++20 flow.cpp tbb12.lib /Fe: m.exe
函数
broadcast_node
join_node
变量
concurrent_map
*/
namespace tpt = tpf::types;
namespace flow = tbb::flow;
tpf::sstream print;
auto& endl = tpf::endl;
auto nl = tpf::nL;
void flow_graph(int N,std::size_t concurrency)
{
auto square = [](int v) -> int
{
return v*v;
};
auto cube = [](int v) -> int
{
return v*v*v;
};
//int result = 0;
// bug fix
// method 2. int result = 0; --> std::atomic<int> result{};
std::atomic<int> result{};
auto sum = [&result](std::tuple<int,int>const& v) ->int
{
result+=std::get<0>(v) + std::get<1>(v);
return result;
};
flow::graph g;
flow::broadcast_node<int> input{g};
// flow::function_node<int,int>
// first int 代表square的输入参数
// second int 代表square的返回值
flow::function_node<int,int>
squarer{g,concurrency,square};
flow::function_node<int,int>
cuber{g,concurrency,cube};
flow::join_node<std::tuple<int,int>,
flow::queueing> join{g};
// bug fix
// method 1. summer{g,concurrency,sum}; --> summer{g,flow::serial,sum};
// use this, we will cannot concurrency.
flow::function_node<std::tuple<int,int>,int> summer{g,concurrency,sum};
flow::make_edge(input,squarer);
flow::make_edge(input,cuber);
flow::make_edge(squarer,std::get<0>( join.input_ports() ) );
flow::make_edge(cuber,std::get<1>( join.input_ports() ) );
flow::make_edge(join,summer);
/*
Edges represent data flow (or message flow)
*/
for(int i = 0; i < N; ++i)
{
input.try_put(i);
}
g.wait_for_all();
print << "Final result is " << result << endl;
}
/*
想获取关于这个问题的一些统计数据
*/
using map_t = tbb::concurrent_map<std::thread::id,int>;
void flow_graph_containers(int N,std::size_t concurrency)
{
map_t square_map;
auto square = [&square_map](int v) -> int
{
square_map[std::this_thread::get_id()] +=1;
return v*v;
};
map_t cube_map;
auto cube = [&cube_map](int v) -> int
{
cube_map[std::this_thread::get_id()] +=1;
return v*v*v;
};
//int result = 0;
std::atomic<int> result{};
auto sum = [&result](std::tuple<int,int>const& v) ->int
{
result+=std::get<0>(v) + std::get<1>(v);
return result;
};
flow::graph g;
flow::broadcast_node<int> input{g};
// flow::function_node<int,int>
// first int 代表square的输入参数
// second int 代表square的返回值
flow::function_node<int,int>
squarer{g,concurrency,square};
flow::function_node<int,int>
cuber{g,concurrency,cube};
flow::join_node<std::tuple<int,int>,
flow::queueing> join{g};
flow::function_node<std::tuple<int,int>,int> summer{g,concurrency,sum};
flow::make_edge(input,squarer);
flow::make_edge(input,cuber);
flow::make_edge(squarer,std::get<0>( join.input_ports() ) );
flow::make_edge(cuber,std::get<1>( join.input_ports() ) );
flow::make_edge(join,summer);
/*
Edges represent data flow (or message flow)
*/
for(int i = 0; i < N; ++i)
{
input.try_put(i);
}
g.wait_for_all();
print << "Final result is " << result << endl;
int square_total = 0;
// 结构化绑定
for(auto& [key,val] : square_map)
square_total +=val;
print << "Square Map Size: " << square_map.size() << ", Total: " << square_total << endl;
print << "Square Map: " << square_map << endl << endl;
int cube_total = 0;
// 结构化绑定
for(auto& [key,val] : cube_map)
cube_total +=val;
print << "Cube Map Size: " << cube_map.size() << ", Total: " << cube_total << endl;
print << "Cube Map: " << cube_map << endl << endl;
}
int main()
{
print << "Serial version" << endl;
flow_graph_containers(100,flow::serial);
print << "Unlimited version" << endl;
flow_graph_containers(100,flow::unlimited);
return 0;
}