summaryrefslogtreecommitdiff
path: root/include/lld/Core/Parallel.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/lld/Core/Parallel.h')
-rw-r--r--include/lld/Core/Parallel.h69
1 files changed, 54 insertions, 15 deletions
diff --git a/include/lld/Core/Parallel.h b/include/lld/Core/Parallel.h
index 2dde97d9e3f0..f241453a4d39 100644
--- a/include/lld/Core/Parallel.h
+++ b/include/lld/Core/Parallel.h
@@ -121,7 +121,7 @@ public:
// Spawn all but one of the threads in another thread as spawning threads
// can take a while.
std::thread([&, threadCount] {
- for (std::size_t i = 1; i < threadCount; ++i) {
+ for (size_t i = 1; i < threadCount; ++i) {
std::thread([=] {
work();
}).detach();
@@ -270,26 +270,65 @@ template <class T> void parallel_sort(T *start, T *end) {
}
#if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0
-template <class Iterator, class Func>
-void parallel_for_each(Iterator begin, Iterator end, Func func) {
- std::for_each(begin, end, func);
+template <class IterTy, class FuncTy>
+void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) {
+ std::for_each(Begin, End, Fn);
+}
+
+template <class IndexTy, class FuncTy>
+void parallel_for(IndexTy Begin, IndexTy End, FuncTy Fn) {
+ for (IndexTy I = Begin; I != End; ++I)
+ Fn(I);
}
#elif defined(_MSC_VER)
// Use ppl parallel_for_each on Windows.
-template <class Iterator, class Func>
-void parallel_for_each(Iterator begin, Iterator end, Func func) {
- concurrency::parallel_for_each(begin, end, func);
+template <class IterTy, class FuncTy>
+void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) {
+ concurrency::parallel_for_each(Begin, End, Fn);
+}
+
+template <class IndexTy, class FuncTy>
+void parallel_for(IndexTy Begin, IndexTy End, FuncTy Fn) {
+ concurrency::parallel_for(Begin, End, Fn);
}
#else
-template <class Iterator, class Func>
-void parallel_for_each(Iterator begin, Iterator end, Func func) {
- TaskGroup tg;
- ptrdiff_t taskSize = 1024;
- while (taskSize <= std::distance(begin, end)) {
- tg.spawn([=, &func] { std::for_each(begin, begin + taskSize, func); });
- begin += taskSize;
+template <class IterTy, class FuncTy>
+void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) {
+ // TaskGroup has a relatively high overhead, so we want to reduce
+ // the number of spawn() calls. We'll create up to 1024 tasks here.
+ // (Note that 1024 is an arbitrary number. This code probably needs
+ // improving to take the number of available cores into account.)
+ ptrdiff_t TaskSize = std::distance(Begin, End) / 1024;
+ if (TaskSize == 0)
+ TaskSize = 1;
+
+ TaskGroup Tg;
+ while (TaskSize <= std::distance(Begin, End)) {
+ Tg.spawn([=, &Fn] { std::for_each(Begin, Begin + TaskSize, Fn); });
+ Begin += TaskSize;
}
- std::for_each(begin, end, func);
+ Tg.spawn([=, &Fn] { std::for_each(Begin, End, Fn); });
+}
+
+template <class IndexTy, class FuncTy>
+void parallel_for(IndexTy Begin, IndexTy End, FuncTy Fn) {
+ ptrdiff_t TaskSize = (End - Begin) / 1024;
+ if (TaskSize == 0)
+ TaskSize = 1;
+
+ TaskGroup Tg;
+ IndexTy I = Begin;
+ for (; I < End; I += TaskSize) {
+ Tg.spawn([=, &Fn] {
+ for (IndexTy J = I, E = I + TaskSize; J != E; ++J)
+ Fn(J);
+ });
+ Begin += TaskSize;
+ }
+ Tg.spawn([=, &Fn] {
+ for (IndexTy J = I; J < End; ++J)
+ Fn(J);
+ });
}
#endif
} // end namespace lld