现代C++ tbb并行库的简单使用 C++20 concept requires的简单使用

#include <tpf_output.hpp>

namespace  tpt = tpf::types;

/*
    编译指令
    clang++ -std=c++20 parallel.cpp -ltbb12 -o c.exe
    g++ -std=c++20 parallel.cpp -ltbb12 -o g.exe
    cl /EHsc /std:c++20 parallel.cpp tbb12.lib /Fe: m.exe
*/

tpf::sstream print;
auto endl = tpf::endl; // flush out to console
auto endL = tpf::endL; // flush out to console
auto nl = "\n";         // new line
auto nL = "\n\n";         // two line

/*
    We use parallel_for_each() for containers that do not support
    random_access_iterators,such as std::list,std::set,ect.

    We use parallel_for() for containers that support
    random_access_iterators,such as std::vector,std::array<>,etc.
*/
void test_parallel_for_each()
{
    // std::list does not support random access iterators
    std::list list{1,2,3,4,5,6,7,8,9,10};

    int sum = 0;

    auto sum_up = [&sum](auto& value)
    {
        sum+=value;
    };

    tbb::parallel_for_each(list.begin(),list.end(),sum_up);

    print << "sum from 1 to 10 equals " << sum << endl;
}

void test_parallel_for_basic()
{
    auto A = tpt::make_container(1,2,3,4.5f,5,6,7,8,9,10);

    int sum = 0;
    auto sum_up = [&sum,&A](const tbb::blocked_range<std::size_t>& r)
    {
        for(auto i = r.begin(); i!=r.end();++i)
        {
            sum+=A[i];
        }
    };

    tbb::parallel_for(tbb::blocked_range{std::size_t{},A.size()},sum_up);
    print << "sum from 1 to 10 equals " << sum << endL;
}

/*
template<typename T>
using void_if_size_available_t = 
    std::enable_if_t<tpt::is_size_available_v< tpt::remove_cvref_t< T > > >;

template<typename T,typename = void_if_size_available_t<T> >
auto get_range(T const& container)
{
    return tbb::blocked_range{std::size_t{},container.size()};
}
*/

/*
    C++20

template<typename T>
auto get_range(T const& container) requires 
    requires
    {
        container.size();  // we text if container has member called "size()"
    }
{
    return tbb::blocked_range{std::size_t{},container.size()};
}
*/

// template<typename T>
//     requires requires(T obj)
//     {
//         obj.size();   // simple requirements
//     }
// auto get_range(T const& container)
// {
//     return tbb::blocked_range{std::size_t{},container.size()};
// }

template<typename T>
concept size_available_c = requires(T obj)
{
    obj.size();     // simple requirements
};

template<size_available_c T>
auto get_range(T const& container)
{
    return tbb::blocked_range{std::size_t{},container.size()};
}

void test_parallel_for_advanced()
{
    auto A = tpt::make_container(1,2,3,4.5f,5,6,7,8,9,10);

    int sum = 0;
    //auto sum_up = [&sum,&A](const tbb::blocked_range<std::size_t>& r)
    auto sum_up = [&sum,&A](auto& r)
    {
        for(auto i = r.begin(); i!=r.end();++i)
        {
            sum+=A[i];
        }
    };
    //tbb::parallel_for(tbb::blocked_range{std::size_t{},A.size()},sum_up);
    tbb::parallel_for(get_range(A),sum_up);
    print << "sum from 1 to 10 equals " << sum << endL;
}

int main()
{
    test_parallel_for_advanced();
    //test_parallel_for_basic();
    // test_parallel_for_each();
}

例子中的函数解释

1、tbb::blocked_range

https://spec.oneapi.io/versions/1.1-rev-1/elements/oneTBB/source/algorithms/blocked_ranges/blocked_range_cls.html

2、tbb::parallel_for

https://oneapi-src.github.io/oneTBB/main/tbb_userguide/parallel_for_os.html

3、tbb::parallel_for_each (tbb::parallel_do is deprecated)

https://oneapi-src.github.io/oneTBB/main/tbb_userguide/Cook_Until_Done_parallel_do.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值