现代C++ 并行程序 Message Flow Graph

使用代码解决上面的问题

一、实例所使用的链接   

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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值