#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