subpar
Substitutable parallelization for C++ libraries
Loading...
Searching...
No Matches
simple.hpp
Go to the documentation of this file.
1#ifndef SUBPAR_SIMPLE_HPP
2#define SUBPAR_SIMPLE_HPP
3
4#ifndef SUBPAR_CUSTOM_PARALLELIZE_SIMPLE
5#include <vector>
6#include <stdexcept>
7#include <thread>
8#include <type_traits>
9#endif
10
16namespace subpar {
17
50template<bool nothrow_ = false, typename Task_, class Run_>
52#ifdef SUBPAR_CUSTOM_PARALLELIZE_SIMPLE
53 if constexpr(nothrow_) {
54#ifdef SUBPAR_CUSTOM_PARALLELIZE_SIMPLE_NOTHROW
56#else
58#endif
59 } else {
61 }
62
63#else
64 if (num_tasks == 0) {
65 return;
66 } else if (num_tasks == 1) {
67 run_task(0);
68 return;
69 }
70
71 // Avoid instantiating a vector if it is known that the function can't throw.
72 typename std::conditional<nothrow_, int, std::vector<std::exception_ptr> >::type errors(num_tasks);
73
74#if defined(_OPENMP) && !defined(SUBPAR_NO_OPENMP_SIMPLE)
75#define SUBPAR_USES_OPENMP_SIMPLE 1
76
77 // OpenMP doesn't guarantee that we'll actually start 'num_tasks' workers,
78 // so we need to do a loop here to ensure that each task simple is executed.
79 #pragma omp parallel for num_threads(num_tasks)
80 for (Task_ w = 0; w < num_tasks; ++w) {
81 if constexpr(nothrow_) {
82 run_task(w);
83 } else {
84 try {
85 run_task(w);
86 } catch (...) {
87 errors[w] = std::current_exception();
88 }
89 }
90 }
91
92#else
93// Wiping it out, just in case.
94#undef SUBPAR_USES_OPENMP_SIMPLE
95
96 std::vector<std::thread> workers;
97 workers.reserve(num_tasks);
98
99 for (Task_ w = 0; w < num_tasks; ++w) {
100 if constexpr(nothrow_) {
101 workers.emplace_back(run_task, w);
102 } else {
103 workers.emplace_back([&run_task,&errors](int w) -> void {
104 try {
105 run_task(w);
106 } catch (...) {
107 errors[w] = std::current_exception();
108 }
109 }, w);
110 }
111 }
112
113 for (auto& wrk : workers) {
114 wrk.join();
115 }
116#endif
117
118 if constexpr(!nothrow_) {
119 for (const auto& e : errors) {
120 if (e) {
121 std::rethrow_exception(e);
122 }
123 }
124 }
125#endif
126}
127
128}
129
130#endif
Substitutable parallelization functions.
void parallelize_range(int num_workers, Task_ num_tasks, Run_ run_task_range)
Parallelize a range of tasks across multiple workers.
Definition range.hpp:126
void parallelize_simple(Task_ num_tasks, Run_ run_task)
Parallelize individual tasks across workers.
Definition simple.hpp:51