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

github.com/Ultimaker/CuraEngine.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRemco Burema <r.burema@ultimaker.com>2021-11-03 18:56:39 +0300
committerRemco Burema <r.burema@ultimaker.com>2021-11-03 20:30:40 +0300
commit7f1cba66105103a26b6c2d1ca98c3ea86e0d431c (patch)
treeb6dbea180f6ff873a7a5240d412a5b38e9f21989 /src
parent9042a0a4e2f31aef5c96d789c01b2ac10d676140 (diff)
'Manual' parallel for loop.
Since not all compilers implement the full C++17 yet, specifically the Parallel Execution TS wasn't added to their respective libraries yet. done as part of CURA-8573
Diffstat (limited to 'src')
-rw-r--r--src/utils/algorithm.h54
1 files changed, 52 insertions, 2 deletions
diff --git a/src/utils/algorithm.h b/src/utils/algorithm.h
index 3cc2fe2d8..adb130ef3 100644
--- a/src/utils/algorithm.h
+++ b/src/utils/algorithm.h
@@ -1,11 +1,13 @@
-/** Copyright (C) 2016 Ultimaker - Released under terms of the AGPLv3 License */
+/** Copyright (C) 2021 Ultimaker - Released under terms of the AGPLv3 License */
#ifndef UTILS_ALGORITHM_H
#define UTILS_ALGORITHM_H
#include <algorithm>
-#include <vector>
+#include <atomic>
#include <functional>
+#include <future>
#include <numeric>
+#include <vector>
// extensions to algorithm.h from the standard library
@@ -41,6 +43,54 @@ std::vector<size_t> order(const std::vector<T> &in)
return order;
}
+/* An implementation of parallel for.
+ * There are still a lot of compilers that claim to be fully C++17 compatible, but don't implement the Parallel Execution TS of the accompanying standard lybrary.
+ * This means that we moslty have to fall back to the things that C++11/14 provide when it comes to threading/parallelism/etc.
+ *
+ * \param from The index starts here (inclusive).
+ * \param to The index ends here (not inclusive).
+ * \param increment Add this to the index each time.
+ * \param body The loop-body, as a closure. Receives the index on invocation.
+ */
+template<typename T>
+void parallel_for(T from, T to, T increment, const std::function<void(const T)>& body)
+{
+ // Sanity tests.
+ assert(increment > 0);
+ assert(from <= to);
+
+ // Set the values so that 'to' is a whole integer multiple apart from 'from' (& early out if needed).
+ to = from + increment * (((to - from) + (increment - static_cast<T>(1))) / increment);
+ if (to == from)
+ {
+ return;
+ }
+
+ // Set an atomic countdown variable to how many tasks need to be completed.
+ std::atomic<T> tasks_pending((to - from) / increment);
+
+ // Wrap the loop-body, so that the outer scope can be notified by 'all_tasks_done'.
+ std::promise<void> all_tasks_done;
+ const auto func =
+ [&body, &tasks_pending, &all_tasks_done](const T index)
+ {
+ body(index);
+ if (--tasks_pending == 0)
+ {
+ all_tasks_done.set_value();
+ }
+ };
+
+ // Run all tasks.
+ for (size_t index = from; index != to; index += increment)
+ {
+ std::async(std::launch::async, func, index);
+ }
+
+ // Wait for the end-result before return.
+ all_tasks_done.get_future().wait();
+}
+
} // namespace cura
#endif // UTILS_ALGORITHM_H