Skip to content

Commit bf9255d

Browse files
committed
Optimization for marl::parallelize
Execute the first function on the calling thread instead of making the fiber immediately block on the wait group. There's a chance that the other functions may have finished by the time the first function finishes, entirely avoiding a fiber switch.
1 parent 3c643dd commit bf9255d

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

include/marl/parallelize.h

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ namespace marl {
2222

2323
namespace detail {
2424

25-
void parallelizeChain(WaitGroup&) {}
25+
inline void parallelizeChain(WaitGroup&) {}
2626

2727
template <typename F, typename... L>
28-
void parallelizeChain(WaitGroup& wg, F&& f, L&&... l) {
28+
inline void parallelizeChain(WaitGroup& wg, F&& f, L&&... l) {
2929
schedule([=] {
3030
f();
3131
wg.done();
@@ -35,13 +35,26 @@ void parallelizeChain(WaitGroup& wg, F&& f, L&&... l) {
3535

3636
} // namespace detail
3737

38-
// parallelize() schedules all the function parameters and waits for them to
39-
// complete. These functions may execute concurrently.
38+
// parallelize() invokes all the function parameters, potentially concurrently,
39+
// and waits for them all to complete before returning.
40+
//
4041
// Each function must take no parameters.
41-
template <typename... FUNCTIONS>
42-
inline void parallelize(FUNCTIONS&&... functions) {
43-
WaitGroup wg(sizeof...(FUNCTIONS));
44-
detail::parallelizeChain(wg, functions...);
42+
//
43+
// parallelize() does the following:
44+
// (1) Schedules the function parameters in the parameter pack fn.
45+
// (2) Calls f0 on the current thread.
46+
// (3) Once f0 returns, waits for the scheduled functions in fn to all
47+
// complete.
48+
// As the fn functions are scheduled before running f0, it is recommended to
49+
// pass the function that'll take the most time as the first argument. That way
50+
// you'll be more likely to avoid the cost of a fiber switch.
51+
template <typename F0, typename... FN>
52+
inline void parallelize(F0&& f0, FN&&... fn) {
53+
WaitGroup wg(sizeof...(FN));
54+
// Schedule all the functions in fn.
55+
detail::parallelizeChain(wg, std::forward<FN>(fn)...);
56+
// While we wait for fn to complete, run the first function on this thread.
57+
f0();
4558
wg.wait();
4659
}
4760

0 commit comments

Comments
 (0)