Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/libslic3r/SLA/Concurrency.hpp')
-rw-r--r--src/libslic3r/SLA/Concurrency.hpp110
1 files changed, 99 insertions, 11 deletions
diff --git a/src/libslic3r/SLA/Concurrency.hpp b/src/libslic3r/SLA/Concurrency.hpp
index 8620c67b1..300024c76 100644
--- a/src/libslic3r/SLA/Concurrency.hpp
+++ b/src/libslic3r/SLA/Concurrency.hpp
@@ -4,6 +4,12 @@
#include <tbb/spin_mutex.h>
#include <tbb/mutex.h>
#include <tbb/parallel_for.h>
+#include <tbb/parallel_reduce.h>
+
+#include <algorithm>
+#include <numeric>
+
+#include <libslic3r/libslic3r.h>
namespace Slic3r {
namespace sla {
@@ -17,18 +23,59 @@ template<bool> struct _ccr {};
template<> struct _ccr<true>
{
using SpinningMutex = tbb::spin_mutex;
- using BlockingMutex = tbb::mutex;
-
+ using BlockingMutex = tbb::mutex;
+
+ 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);
+ }
+
template<class It, class Fn>
- static inline void enumerate(It from, It to, Fn fn)
+ static void for_each(It from, It to, Fn &&fn, size_t granularity = 1)
{
- auto iN = to - from;
- size_t N = iN < 0 ? 0 : size_t(iN);
-
- tbb::parallel_for(size_t(0), N, [from, fn](size_t n) {
- fn(*(from + decltype(iN)(n)), n);
+ tbb::parallel_for(tbb::blocked_range{from, to, granularity},
+ [&fn, from](const auto &range) {
+ loop_(range, std::forward<Fn>(fn));
});
}
+
+ template<class I, class MergeFn, class T, class AccessFn>
+ static T reduce(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));
+ }
+
+ template<class I, class MergeFn, class T>
+ static IteratorOnly<I, T> reduce(I from,
+ I to,
+ const T & init,
+ MergeFn &&mergefn,
+ size_t granularity = 1)
+ {
+ return reduce(
+ from, to, init, std::forward<MergeFn>(mergefn),
+ [](typename I::value_type &i) { return i; }, granularity);
+ }
};
template<> struct _ccr<false>
@@ -39,11 +86,52 @@ private:
public:
using SpinningMutex = _Mtx;
using BlockingMutex = _Mtx;
-
+
+ template<class Fn, class It>
+ static IteratorOnly<It, void> loop_(It from, It to, Fn &&fn)
+ {
+ for (auto it = from; it != to; ++it) fn(*it);
+ }
+
+ template<class Fn, class I>
+ static IntegerOnly<I, void> loop_(I from, I to, Fn &&fn)
+ {
+ for (I i = from; i < to; ++i) fn(i);
+ }
+
template<class It, class Fn>
- static inline void enumerate(It from, It to, Fn fn)
+ static void for_each(It from,
+ It to,
+ Fn &&fn,
+ size_t /* ignore granularity */ = 1)
+ {
+ loop_(from, to, std::forward<Fn>(fn));
+ }
+
+ template<class I, class MergeFn, class T, class AccessFn>
+ static T reduce(I from,
+ I to,
+ const T & init,
+ MergeFn &&mergefn,
+ AccessFn &&access,
+ size_t /*granularity*/ = 1
+ )
+ {
+ T acc = init;
+ loop_(from, to, [&](auto &i) { acc = mergefn(acc, access(i)); });
+ return acc;
+ }
+
+ template<class I, class MergeFn, class T>
+ static IteratorOnly<I, T> reduce(I from,
+ I to,
+ const T &init,
+ MergeFn &&mergefn,
+ size_t /*granularity*/ = 1
+ )
{
- for (auto it = from; it != to; ++it) fn(*it, size_t(it - from));
+ return reduce(from, to, init, std::forward<MergeFn>(mergefn),
+ [](typename I::value_type &i) { return i; });
}
};