PrusaSlicer/src/libslic3r/Execution/ExecutionTBB.hpp
Roman Beránek e13535f822
drop deprecated TBB components (#6590)
Quite some time ago, many of the TBB components were deprecated in favor
of their near-equivalents in the STL or, in the case of task_scheduler_init,
were broken up and reconstituted under a less ad-hoc logic. Every time a header
file marked deprecated gets included, a rather loud warning is emitted, which
leads to a complete TBB's domination over the stderr stream during build time,
making it harder to notice _legitimate_ warnings.

Instead of merely muting the output with TBB_SUPPRESS_DEPRECATED_MESSAGES,
perform a genuine migration away from the deprecated components with the added
benefit of achieving a source compatibility with oneTBB, the successor to TBB
which has dropped the deprecated API for good.

What got replaced for what?

| Deprecated				| Replacement					|
| ------------------------------------- | --------------------------------------------- |
| `tbb::atomic`				| `std::atomic`					|
| `tbb::mutex`				| `std::mutex`					|
| `tbb::mutex::scoped_lock`		| `std::scoped_lock<std::mutex>`		|
| `tbb::mutex::scoped_lock` (empty)	| `std::unique_lock<std::mutex>` (deferred)	|
| `tbb::task_scheduler_init`		| `tbb::global_control`				|
| `tbb::this_thread`			| `std::this_thread`				|

Signed-off-by: Roman Beranek <roman.beranek@prusa3d.com>
2021-06-23 11:48:48 +02:00

79 lines
2.1 KiB
C++

#ifndef EXECUTIONTBB_HPP
#define EXECUTIONTBB_HPP
#include <mutex>
#include <tbb/spin_mutex.h>
#include <tbb/parallel_for.h>
#include <tbb/parallel_reduce.h>
#include <tbb/task_arena.h>
#include "Execution.hpp"
namespace Slic3r {
struct ExecutionTBB {};
template<> struct IsExecutionPolicy_<ExecutionTBB> : public std::true_type {};
// Execution policy using Intel TBB library under the hood.
static constexpr ExecutionTBB ex_tbb = {};
template<> struct execution::Traits<ExecutionTBB> {
private:
template<class Fn, class It>
static IteratorOnly<It, void> loop_(const tbb::blocked_range<It> &range, Fn &&fn)
{
for (auto &el : range) fn(el);
}
template<class Fn, class I>
static IntegerOnly<I, void> loop_(const tbb::blocked_range<I> &range, Fn &&fn)
{
for (I i = range.begin(); i < range.end(); ++i) fn(i);
}
public:
using SpinningMutex = tbb::spin_mutex;
using BlockingMutex = std::mutex;
template<class It, class Fn>
static void for_each(const ExecutionTBB &,
It from, It to, Fn &&fn, size_t granularity)
{
tbb::parallel_for(tbb::blocked_range{from, to, granularity},
[&fn](const auto &range) {
loop_(range, std::forward<Fn>(fn));
});
}
template<class I, class MergeFn, class T, class AccessFn>
static T reduce(const ExecutionTBB &,
I from,
I to,
const T &init,
MergeFn &&mergefn,
AccessFn &&access,
size_t granularity = 1
)
{
return tbb::parallel_reduce(
tbb::blocked_range{from, to, granularity}, init,
[&](const auto &range, T subinit) {
T acc = subinit;
loop_(range, [&](auto &i) { acc = mergefn(acc, access(i)); });
return acc;
},
std::forward<MergeFn>(mergefn));
}
static size_t max_concurrency(const ExecutionTBB &)
{
return tbb::this_task_arena::max_concurrency();
}
};
}
#endif // EXECUTIONTBB_HPP